<?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: Michael R.</title>
    <description>The latest articles on DEV Community by Michael R. (@killshot13).</description>
    <link>https://dev.to/killshot13</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%2F497515%2F9113bec9-139f-4100-8f2f-1affcd01fd28.jpg</url>
      <title>DEV Community: Michael R.</title>
      <link>https://dev.to/killshot13</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/killshot13"/>
    <language>en</language>
    <item>
      <title>"Apple Music" Sent a Renewal Email to my Android…</title>
      <dc:creator>Michael R.</dc:creator>
      <pubDate>Wed, 12 Nov 2025 11:47:50 +0000</pubDate>
      <link>https://dev.to/killshot13/apple-music-sent-a-renewal-email-to-my-android-15bg</link>
      <guid>https://dev.to/killshot13/apple-music-sent-a-renewal-email-to-my-android-15bg</guid>
      <description>&lt;blockquote&gt;
&lt;h2&gt;
  
  
  Ever gotten an email from a reputable company like Apple, Verizon, or Coinbase, but something feels a bit off about it?
&lt;/h2&gt;
&lt;/blockquote&gt;



&lt;ul&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;
How to ID Spam/Phishing Email?

&lt;ul&gt;
&lt;li&gt;Check the Preview&lt;/li&gt;
&lt;li&gt;Check the Body&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

Why ID Spam/Phishing Email?

&lt;ul&gt;
&lt;li&gt;Malicious Intent&lt;/li&gt;
&lt;li&gt;Hostile Takeovers&lt;/li&gt;
&lt;li&gt;Global Threat Actors&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

Summary

&lt;ul&gt;
&lt;li&gt;Red Flags (Email Preview)&lt;/li&gt;
&lt;li&gt;Red Flags (Email Body)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;






&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Most of us are aware, to some extent, of the danger posed by suspicious emails. But if your inbox is like mine, with 20–30 new emails arriving daily, finding enough time to skim them can be overwhelming, much less tell which ones are suspect. Seems absurd.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to ID Spam/Phishing Email?
&lt;/h2&gt;

&lt;p&gt;Maybe, like I once did, you naïvely assume these emails all magically end up in the Junk/Spam folder. But can we really trust our spam filter to catch 'em all? (even Ash didn't pull that one off) Perhaps try the latest freemium plugin instead? As if we can even afford that after rent and bills, right?&lt;/p&gt;

&lt;h3&gt;
  
  
  Check the Preview
&lt;/h3&gt;

&lt;p&gt;Ironically, I received an email earlier today that managed to bypass my spam filter, security add-ons, and custom rules and somehow landed in my Focused Inbox (equivalent to 'Important' in Gmail). But as soon as I glanced at the preview, red flags started to pop up, including sloppy font styling, a vague subject line, and a deadline in mere hours. Let's take a look.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fea9k6lg5cr3ypmn2yo1n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fea9k6lg5cr3ypmn2yo1n.png" alt="A preview of a suspected phishing email with three distinct red flags" width="800" height="937"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;At this point, in most cases, we already have sufficient circumstantial evidence to justify deleting the email without even opening it. Why waste time entertaining spam or potential malware?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Report the email as junk so that anything from that sender will be filtered automatically; then, delete it to avoid accidentally clicking on it later.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Check the Body
&lt;/h3&gt;

&lt;p&gt;But let's assume, for the sake of argument, that we already opened the email. Can we expect to see additional new red flags or just variants of those previously covered? Let's see what else we should be aware of.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn6i1fznzucpmqtwt3n7d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn6i1fznzucpmqtwt3n7d.png" alt="The main body of a suspected phishing email with three additional red flags" width="800" height="1107"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;After the FOMO pitch, fake Apple Music icon, and wildly inaccurate company details in the footer, I am positive Apple did not send this email. A reputable company would never be so sloppy. That being said, now I'm curious about the demise someone evidently had in mind for me. What if, half-awake or intoxicated, I had instead chosen to &lt;em&gt;Renew my subscription&lt;/em&gt;?&lt;/p&gt;

&lt;h2&gt;
  
  
  Why ID Spam/Phishing Email?
&lt;/h2&gt;

&lt;p&gt;Using extreme caution to avoid actually clicking the link, I combed through the original message using source view, located the embedded URL, and submitted it to &lt;a href="https://www.virustotal.com/gui/url/de3d5e9726eb4f433e8565bd4cdf9d9d0b340efcfbdb243f01a627322c22a323/details" rel="noopener noreferrer"&gt;VirusTotal&lt;/a&gt; for analysis.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Disclaimer: DO NOT interact with suspected spam or malicious content unless you understand the risks and have a valid reason for doing so.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Malicious Intent
&lt;/h3&gt;

&lt;p&gt;The verdict was returned in under a minute, with vendor flags thrown for malicious content and phishing.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjgur0ausjkh73mbfu0kq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjgur0ausjkh73mbfu0kq.png" alt="A VirusTotal report flagging the URL as malicious or phishing." width="800" height="1119"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Hostile Takeovers
&lt;/h3&gt;

&lt;p&gt;Chaos ensues as the malware deletes the trusted/disallowed cert lists. Clearly, the rabbit hole went very deep, far beyond my expectations.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbqd7pzwlz7xett1lpv6n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbqd7pzwlz7xett1lpv6n.png" alt="A VirusTotal report detailing the malware behavior" width="800" height="1221"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Global Threat Actors
&lt;/h3&gt;

&lt;p&gt;Lastly, note the actual destination of that link from the email. Far removed from anything related to Apple, it belongs to a ball bearing dealer in India.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi6er1i1f6ohinglf1mc9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi6er1i1f6ohinglf1mc9.png" alt="A VirusTotal report showing the final URL resolving to a domain in India" width="676" height="344"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Okay, and on that note, let's recap…&lt;/p&gt;

&lt;p&gt;Next time those unread emails start piling up, apply what we learned today. Scan the previews, look for red flags, and deal with any obvious spam first.&lt;/p&gt;

&lt;h3&gt;
  
  
  Red Flags (Email Preview)
&lt;/h3&gt;

&lt;p&gt;🚩- Visible changes in font size and thickness&lt;br&gt;
🚩- Unclear or vague origin and subject line&lt;br&gt;
🚩- Deadline in a few hours to trigger a rushed response&lt;/p&gt;

&lt;p&gt;Now you can open and read the emails that appear legitimate, but stay vigilant, checking for suspicious details and not clicking on any links.&lt;/p&gt;

&lt;h3&gt;
  
  
  Red Flags (Email Body)
&lt;/h3&gt;

&lt;p&gt;🚩- Fear of Missing Out (FOMO) emphasized in the message body&lt;br&gt;
🚩- Icons or logos that appear fuzzy, altered, or modified&lt;br&gt;
🚩- Inaccurate company name, address, or contact info&lt;/p&gt;

&lt;p&gt;Finally, trust but verify. Except for actively generated security verification emails, use a website or app to log in directly, not an email link. At this point, you can both validate the email and conduct any necessary business.&lt;/p&gt;

&lt;p&gt;At the risk of sounding cliché, better to be safe than sorry!&lt;/p&gt;

&lt;p&gt;-killshot13&lt;/p&gt;




&lt;p&gt;Don't forget to 💖 this article and leave a 🗨️; I look forward to reading your thoughts and opinions in the comments below.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Image Credit: "@theRealAppleMusic", adapted from "&lt;a href="https://lirp.cdn-website.com/7825253e/dms3rep/multi/opt/UnKnown+Caller-1920w.jpg" rel="noopener noreferrer"&gt;UnKnown Caller&lt;/a&gt;" by &lt;a href="https://www.acdtn.com/contact#AboutUsPicanchor" rel="noopener noreferrer"&gt;Rick Patin&lt;/a&gt;, used under &lt;a href="http://creativecommons.org/licenses/by/4.0" rel="noopener noreferrer"&gt;CC BY 4.0&lt;/a&gt;. "@theRealAppleMusic" is licensed under &lt;a href="http://creativecommons.org/licenses/by/4.0" rel="noopener noreferrer"&gt;CC BY 4.0&lt;/a&gt; by &lt;a href="https://dev.to/killshot13"&gt;Michael R&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>cybersecurity</category>
      <category>security</category>
      <category>learning</category>
      <category>resources</category>
    </item>
    <item>
      <title>Configuring VSCode Colorized Brackets</title>
      <dc:creator>Michael R.</dc:creator>
      <pubDate>Fri, 31 Dec 2021 14:32:31 +0000</pubDate>
      <link>https://dev.to/killshot13/configuring-vscode-colorized-brackets-5733</link>
      <guid>https://dev.to/killshot13/configuring-vscode-colorized-brackets-5733</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;Most of us likely still remember that initial feeling of amazement after installing the the wildly popular but now deprecated &lt;a href="https://marketplace.visualstudio.com/items?itemName=CoenraadS.bracket-pair-colorizer" rel="noopener noreferrer"&gt;Bracket Pair Colorizer&lt;/a&gt; extension by &lt;a href="https://marketplace.visualstudio.com/publishers/CoenraadS" rel="noopener noreferrer"&gt;CoenraadS&lt;/a&gt;. After over 10M+ downloads, the options once delivered by that extension have now become native features in VS Code. &lt;/p&gt;

&lt;p&gt;At first, I found it difficult to achieve the same level of comfort and functionality offered by Bracket Pair Colorizer. And judging from the nearly &lt;a href="https://github.com/microsoft/vscode/issues?q=is%3Aissue+bracket+colorization" rel="noopener noreferrer"&gt;100 issues&lt;/a&gt; opened on GitHub, I was not alone. That said, the VS Code team has changed my impression with their &lt;a href="https://code.visualstudio.com/updates/v1_62#_editor" rel="noopener noreferrer"&gt;latest feature update&lt;/a&gt; this past October.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://code.visualstudio.com/updates/v1_62" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F68otksnjnsmlkeg9e4js.jpg" alt="editor.guides.highlightActiveIndentation" width="350" height="264"&gt;&lt;/a&gt;Vertical lines now depend on the indentation of the code that is surrounded by the bracket pair. (Image: Microsoft) &lt;/p&gt;




&lt;h2&gt;
  
  
  Discover What's New
&lt;/h2&gt;

&lt;p&gt;I will cover each of the aforementioned updates briefly before sharing the configuration I am now using in VS Code. So without further ado, let's check out these new features! 😎&lt;/p&gt;

&lt;h3&gt;
  
  
  Bracket Pairs
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Indentation of bracket characters can now be customized based on the programming language being used. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Colorization of bracket characters can now be defined based on functionality which is inferred from the depth of nesting.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Bracket Pair Guides
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Horizontal lines now outline the scope of a bracket pair.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Vertical lines now depend on how the code within the bracket pair is indented.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Bracket pair guides now have a third option, 'active', providing a more granular level of control over colorized highlights.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;🎉 Guide highlights now support color customizations! 🎉&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Custom Settings Example
&lt;/h2&gt;

&lt;p&gt;Now that we have an idea of the possibilities, here is a working example, copied from my &lt;code&gt;settings.json&lt;/code&gt; as promised. It has been freshly revised to take advantage of the new updates.&lt;/p&gt;





&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
The relevant changes made to the &lt;code&gt;settings.json&lt;/code&gt; file.




&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkizqmty89gpgdlb6xt0m.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkizqmty89gpgdlb6xt0m.jpg" alt="Sample Code w/ Colorized Brackets" width="800" height="532"&gt;&lt;/a&gt;Shows these settings applied to brackets in different languages.&lt;/p&gt;


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

&lt;p&gt;You now have a good starting point for creating a customized bracket pair colorization that works well for you. Of course, I was not able to cover every setting and variable in this short article. &lt;/p&gt;

&lt;p&gt;There are many options which you can enable or disable to optimize your VS Code experience. Remember you can always reference the &lt;a href="https://code.visualstudio.com/docs/getstarted/settings#_default-settings" rel="noopener noreferrer"&gt;default settings&lt;/a&gt; in case your &lt;code&gt;settings.json&lt;/code&gt; file is or becomes a bit disorganized.&lt;/p&gt;

&lt;p&gt;I'm excited to see the configurations and themes you all create using these new feature, so please leave a screenshot or code snippet in the comments.&lt;/p&gt;

&lt;p&gt;Don't forget to 💖 this article and if you're feeling extra generous, please click my name below to 🎆subscribe🎇!&lt;/p&gt;

&lt;p&gt;-- killshot13&lt;/p&gt;




&lt;div class="ltag__user ltag__user__id__497515"&gt;
    &lt;a href="/killshot13" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&gt;
        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F497515%2F9113bec9-139f-4100-8f2f-1affcd01fd28.jpg" alt="killshot13 image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/killshot13"&gt;Michael R.&lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/killshot13"&gt;Full-Stack Web Developer— Websites · Web Applications · WordPress · SEO · MongoDB · UGA/GA4 Certified · Windows Insider · WP Core · Ethical Hacker · USAF Veteran&lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;


</description>
      <category>vscode</category>
      <category>productivity</category>
      <category>tooling</category>
      <category>functional</category>
    </item>
    <item>
      <title>Best Practices: Sign-In Forms</title>
      <dc:creator>Michael R.</dc:creator>
      <pubDate>Fri, 30 Jul 2021 10:18:48 +0000</pubDate>
      <link>https://dev.to/killshot13/best-practices-sign-in-forms-d8e</link>
      <guid>https://dev.to/killshot13/best-practices-sign-in-forms-d8e</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;This article specifically focuses on the design and development of sign-in forms and should be used as a reference only in this scope. &lt;/p&gt;

&lt;p&gt;It does not seek to provide a comprehensive guide to building web forms and should not be regarded as such. &lt;/p&gt;




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

&lt;p&gt;1 — HTML&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;1.1 — HTML Code Example&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;2 — Types &amp;amp; Attributes&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;2.1 — Types&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;2.1.1 — Code Examples Using Types&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;2.2. — Attributes&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;2.2.1 — Code Examples Using Attributes&lt;/p&gt;
&lt;/blockquote&gt;


&lt;/blockquote&gt;

&lt;p&gt;3 — CSS&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;3.1 — CSS Code Examples&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;4 — JS&lt;/p&gt;

&lt;p&gt;5 — A Quick Recap&lt;/p&gt;

&lt;p&gt;6 — References&lt;/p&gt;




&lt;h2&gt;
  
  
  HTML
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Give each input its own &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt; element, and prefer &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt; over &lt;code&gt;&amp;lt;placeholder&amp;gt;&lt;/code&gt; if you must choose between the two. While &lt;code&gt;&amp;lt;placeholder&amp;gt;&lt;/code&gt; tags can be useful, they should NOT be used to substitute or replace &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt; elements.&lt;/li&gt;
&lt;li&gt;Place the &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt; element above the &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; element.&lt;/li&gt;
&lt;li&gt;Don't force users to input information twice; yes, this extends to emails and passwords. Instead, have them confirm their account ownership by sending a confirmation email and make it simple for them to reset their password.&lt;/li&gt;
&lt;/ul&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"When designing sign-in forms, strive to enforce the password &lt;strong&gt;quality&lt;/strong&gt; over the password &lt;strong&gt;quantity&lt;/strong&gt;."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt; tags for buttons, and make consider making &lt;code&gt;"SUBMIT"&lt;/code&gt; buttons more descriptive. Use wording like &lt;code&gt;"Sign In"&lt;/code&gt; or &lt;code&gt;"Subscribe"&lt;/code&gt; so the user knows what to expect after clicking.&lt;/li&gt;
&lt;li&gt;A basic sign-in form should use the applicable HTML elements for each part instead of a cluster of &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; elements rendered with countless extra lines of JavaScript.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  HTML Code Example
&lt;/h3&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;form&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;section&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Email&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/section&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;section&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"password"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Password&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"password"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/section&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;button&amp;gt;&lt;/span&gt;Sign In&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Types &amp;amp; Attributes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Additional details can (and should) be added to sign-in forms, providing additional context to the browser.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; tag, along with its HTML siblings &lt;code&gt;&amp;lt;select&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;textarea&amp;gt;,&lt;/code&gt; accepts two kinds of parameters— types and attributes.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Types
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The value of type defaults to &lt;code&gt;"text"&lt;/code&gt;, but &lt;code&gt;"email"&lt;/code&gt; and &lt;code&gt;"password"&lt;/code&gt; are the preferred types to use with their respective inputs.&lt;/li&gt;
&lt;li&gt;Password inputs should always define their type as such &lt;code&gt;&amp;lt;input type=password&amp;gt;&lt;/code&gt; for security purposes. This signals the browser to render the user's password hidden by default.&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;
  
  
  Code Examples Using Types
&lt;/h3&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;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"password"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt; // or // &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Attributes
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;As with types, some attributes, like &lt;code&gt;autocomplete,&lt;/code&gt; can smooth out the user experience when signing in.&lt;/li&gt;
&lt;li&gt;Modern browsers use inference from these attributes to help decide when to display a password strength meter, offer to save a new or updated password, or autocomplete the form with credentials previously stored on the user's behalf.&lt;/li&gt;
&lt;li&gt;A quality sign-in form will add the &lt;code&gt;autocomplete&lt;/code&gt; attribute to all relevant inputs, allowing the browser's settings and/or the user's preferences to decide how to utilize the provided hints.&lt;/li&gt;
&lt;li&gt;In addition, the &lt;code&gt;required&lt;/code&gt; attribute can (and should) be used in all email/username and password fields.&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;
  
  
  Code Examples Using Attributes
&lt;/h3&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;input&lt;/span&gt; &lt;span class="na"&gt;type-&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt; &lt;span class="na"&gt;autocomplete=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;autocomplete=&lt;/span&gt;&lt;span class="s"&gt;"username"&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"password"&lt;/span&gt; &lt;span class="na"&gt;autocomplete=&lt;/span&gt;&lt;span class="s"&gt;"new-password"&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt; 
    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"password"&lt;/span&gt; &lt;span class="na"&gt;autocomplete=&lt;/span&gt;&lt;span class="s"&gt;"current-password"&lt;/span&gt; 
    &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"number"&lt;/span&gt; &lt;span class="na"&gt;autocomplete=&lt;/span&gt;&lt;span class="s"&gt;"one-time-code"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  CSS
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Use approximately 16px/1rem of padding for mobile as a general rule of thumb.&lt;/li&gt;
&lt;li&gt;Same as above, but only 10px/0.625rem on the desktop.&lt;/li&gt;
&lt;li&gt;All inputs and buttons should be visible and give enough room to tap each element in mobile view.&lt;/li&gt;
&lt;li&gt;Design for thumbs, not fingers.&lt;/li&gt;
&lt;li&gt;Increase &lt;code&gt;font-size&lt;/code&gt; on mobile by at least 2px. Sometimes up to 4px may be necessary with specific fonts.&lt;/li&gt;
&lt;li&gt;Leverage the browser's built-in ability to detect invalid input. You don't need JavaScript; render the &lt;code&gt;:invalid&lt;/code&gt; attribute with &lt;code&gt;&amp;lt;color: red&amp;gt;&lt;/code&gt; in the CSS.&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;
  
  
  CSS Code Examples
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;
    &lt;span class="c"&gt;/** GOOD */&lt;/span&gt;
    &lt;span class="nt"&gt;input&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nt"&gt;email&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="nd"&gt;:invalid&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;/** EVEN BETTER */&lt;/span&gt;
    &lt;span class="nt"&gt;input&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nt"&gt;email&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="nd"&gt;:not&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;:placeholder-shown&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="nd"&gt;:invalid&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;red&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;
  
  
  JS
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Make sure the sign-in button stays visible on mobile and doesn't get covered by the keyboard. One nearly fail-safe way to accomplish this is only to request the email on the initial screen, then defer to a second screen before requiring the password input.&lt;/li&gt;
&lt;li&gt;Use JavaScript to render a &lt;code&gt;"SHOW PASSWORD"&lt;/code&gt; icon or text button.&lt;/li&gt;
&lt;li&gt;IMPORTANT: Provide additional form validation to sanitize user input before sending it to the server by checking against the expected REGEX cases and MIME types.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  A Quick Recap
&lt;/h2&gt;

&lt;p&gt;Let me condense everything you have just read into two sentences containing the key takeaways.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Most sign-in forms can provide the same level of functionality or even better by leveraging the native ability of HTML5 and CSS while using less JavaScript. This approach delivers improvements on many fundamental levels, including accessibility, Core Web Vitals, PWA criteria, and design simplicity.&lt;/p&gt;
&lt;/blockquote&gt;



&lt;p&gt;To view the list of references I consulted for this article, please scroll to the bottom of the page; perhaps you will find them helpful.&lt;/p&gt;

&lt;p&gt;Don't forget to 💖 this article and leave a 💭. If you're feeling extra generous, please click my name below to 🎆subscribe🎇!&lt;/p&gt;

&lt;p&gt;Thank you for reading!&lt;/p&gt;

&lt;p&gt;-- killshot13&lt;/p&gt;




&lt;div class="ltag__user ltag__user__id__497515"&gt;
    &lt;a href="/killshot13" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&gt;
        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F497515%2F9113bec9-139f-4100-8f2f-1affcd01fd28.jpg" alt="killshot13 image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/killshot13"&gt;Michael R.&lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/killshot13"&gt;Full-Stack Web Developer— Websites · Web Applications · WordPress · SEO · MongoDB · UGA/GA4 Certified · Windows Insider · WP Core · Ethical Hacker · USAF Veteran&lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;






&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://web.dev/codelab-sign-in-form-best-practices/" rel="noopener noreferrer"&gt;Use cross-platform browser features to build a sign-in form&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://safethishome.com/decoding-password-security-six-key-password-tips-for-2021/" rel="noopener noreferrer"&gt;Decoding password security: Six key password tips for 2021&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input" rel="noopener noreferrer"&gt;&amp;lt;.input&amp;gt;: The Input (Form Input) element&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>html</category>
      <category>css</category>
      <category>webdev</category>
      <category>ux</category>
    </item>
    <item>
      <title>mdEditor (for VSCode)</title>
      <dc:creator>Michael R.</dc:creator>
      <pubDate>Mon, 28 Jun 2021 16:12:41 +0000</pubDate>
      <link>https://dev.to/killshot13/mdeditor-for-vscode-16nn</link>
      <guid>https://dev.to/killshot13/mdeditor-for-vscode-16nn</guid>
      <description>&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Overview&lt;/li&gt;
&lt;li&gt;Features&lt;/li&gt;
&lt;li&gt;Prerequisites&lt;/li&gt;
&lt;li&gt;Installation&lt;/li&gt;
&lt;li&gt;Usage&lt;/li&gt;
&lt;li&gt;Credits&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Overview (TL;DR) &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;In a nutshell, mdEditor is a VS Code Workspace that can be installed from GitHub. It creates a sort of self-contained Markdown environment on your local machine. &lt;/p&gt;

&lt;p&gt;mdEditor provides the configuration guidelines and creates the structure for an awesome VSCode Markdown editor. By creating a reusable Code-Workspace, the main portion of your IDE environment is protected from rule conflicts.&lt;/p&gt;




&lt;h2&gt;
  
  
  Features &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;The Code-Workspace, once opened with VS Code, loads everything you need for importing, exporting, linting, custom rulesets, automatic styling, and file conversion --&amp;gt; PDF, DOCX, and HTML.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The syntax rules allow for the enforcement of any markdown flavor with a simple on/off option for each rule.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The linter looks for errors/problems and immediately flags them. A detailed explanation and reference link will appear on hover.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The auto-fix feature is enabled by default to run each time a file is saved. This formats your Markdown using the enabled rules, which corrects most errors automatically with no manual edits needed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The file conversion tool uses an extension to integrate Pandoc with VS Code. With a simple key-binding (&lt;code&gt;CTRL + K&lt;/code&gt;, &lt;code&gt;P&lt;/code&gt;), you can create &lt;code&gt;.pdf&lt;/code&gt;, &lt;code&gt;.docx&lt;/code&gt;, and &lt;code&gt;.html&lt;/code&gt; files from Markdown, after which the new files can be viewed immediately and/or exported elsewhere.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The default stylesheet is applied during file conversion, ensuring  uniformity and consistency in the output. You can apply custom styles using CSS to achieve the desired appearance of the converted files.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Prerequisites &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://code.visualstudio.com/Download" rel="noopener noreferrer"&gt;Visual Studio Code&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
This should be self-explanatory.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="http://pandoc.org/installing.html" rel="noopener noreferrer"&gt;Pandoc&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
This may require some guidance if you don't currently use Pandoc. I wrote a gist to help first-time users; here is &lt;a href="https://gist.github.com/killshot13/5b379355d275e79a5cb1f03c841c7d53" rel="noopener noreferrer"&gt;the link&lt;/a&gt;.&lt;/p&gt;


&lt;h3&gt;
  
  
  Installation &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;mdEditor can be installed using the simple guide you are reading now, which paraphrases the README.md file from the &lt;a href="https://github.com/killshot13/mdEditor" rel="noopener noreferrer"&gt;main repository&lt;/a&gt;.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/killshot13" rel="noopener noreferrer"&gt;
        killshot13
      &lt;/a&gt; / &lt;a href="https://github.com/killshot13/mdEditor" rel="noopener noreferrer"&gt;
        mdEditor
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Awesome markdown editor for VS Code. Supports linting and prints to HTML, PDF, and MS Word (Docx)!
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Decide where the root directory of the editor is going to live on your local drive (reference Overview for details), then clone &lt;a href="https://github.com/killshot13/mdEditor.git" rel="noopener noreferrer"&gt;mdEditor&lt;/a&gt; to that location.&lt;/p&gt;

&lt;p&gt;Now, open mdEditor at the base directory using VSCode. Your IDE will auto-discover the &lt;code&gt;.code-workspace&lt;/code&gt; file and prompt you to reopen the folder as a workspace. &lt;/p&gt;

&lt;p&gt;Confirm this choice, unless you want a different configuration. If so, there is a blank &lt;code&gt;settings.json&lt;/code&gt; in the &lt;code&gt;.vscode&lt;/code&gt; folder for you. Otherwise, just delete that file to avoid confusion.&lt;/p&gt;

&lt;p&gt;Once open, you should receive another prompt to install the recommended VS Code extensions. Once again, choose confirm to install, and leave the default settings in place. &lt;/p&gt;

&lt;p&gt;The extensions will power the linting rules and Pandoc style guide within the workspace. Here are the links in case you encounter any issues.&lt;/p&gt;

&lt;p&gt;--&amp;gt; &lt;a href="https://marketplace.visualstudio.com/items?itemName=DavidAnson.vscode-markdownlint" rel="noopener noreferrer"&gt;markdownlint&lt;/a&gt;&lt;br&gt;
--&amp;gt; &lt;a href="https://marketplace.visualstudio.com/items?itemName=DougFinke.vscode-pandoc" rel="noopener noreferrer"&gt;vscode-pandoc&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, using this diagram, verify the file structure of your local installation of mdEditor is a rough match.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    &lt;span class="k"&gt;**&lt;/span&gt;Tree View&lt;span class="k"&gt;**&lt;/span&gt;
    _mdEditor_
    &lt;span class="se"&gt;\+&lt;/span&gt;&lt;span class="nt"&gt;---&lt;/span&gt;.vscode
         |       &lt;span class="sb"&gt;`&lt;/span&gt;settings.json&lt;span class="sb"&gt;`&lt;/span&gt;
         |
         +---md
         |       &lt;span class="sb"&gt;`&lt;/span&gt;project1.md&lt;span class="sb"&gt;`&lt;/span&gt;
         |       &lt;span class="sb"&gt;`&lt;/span&gt;project2.md&lt;span class="sb"&gt;`&lt;/span&gt;
         |
         +---styles
         |       &lt;span class="sb"&gt;`&lt;/span&gt;style.css&lt;span class="sb"&gt;`&lt;/span&gt;
         |       &lt;span class="sb"&gt;`&lt;/span&gt;syntax.md&lt;span class="sb"&gt;`&lt;/span&gt;
         |
         |&lt;span class="sb"&gt;`&lt;/span&gt;.markdownlint.json&lt;span class="sb"&gt;`&lt;/span&gt;
         |&lt;span class="sb"&gt;`&lt;/span&gt;mdEditor.code-workspace&lt;span class="sb"&gt;`&lt;/span&gt;
         |&lt;span class="sb"&gt;`&lt;/span&gt;README.md&lt;span class="sb"&gt;`&lt;/span&gt;
         |&lt;span class="sb"&gt;`&lt;/span&gt;LICENSE&lt;span class="sb"&gt;`&lt;/span&gt;
         &lt;span class="se"&gt;\-&lt;/span&gt;&lt;span class="nt"&gt;--&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;NOTE: On Linux you must uncomment the &lt;code&gt;pandoc.htmlOptString&lt;/code&gt; in the &lt;code&gt;mdEditor.code-workspace&lt;/code&gt; file. The current version, which uses Windows OS file separators, must be replaced with the Linux version; otherwise, the css styles will not be applied correctly.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Installation is complete.&lt;br&gt;
Nice job!&lt;/p&gt;


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

&lt;p&gt;To test linting &amp;amp; formatting, click the &lt;code&gt;test.txt&lt;/code&gt; file (in the &lt;code&gt;md&lt;/code&gt; folder); it should open in the main editor window.&lt;/p&gt;

&lt;p&gt;In the sidebar, keeping the &lt;code&gt;test.txt&lt;/code&gt; tab in focus, change the filetype from &lt;code&gt;txt&lt;/code&gt; to &lt;code&gt;md&lt;/code&gt; and save.&lt;/p&gt;

&lt;p&gt;Check the output in the PROBLEMS tab of your lower (terminal) panel. Several formatting violations should appear. Now make a tiny edit and save again. Most of the errors should be gone, having been corrected automatically.&lt;/p&gt;

&lt;p&gt;To test the filetype output, enter the key combination &lt;code&gt;CTRL + K&lt;/code&gt;, then press &lt;code&gt;P&lt;/code&gt;. Options to create &lt;code&gt;.pdf&lt;/code&gt;, &lt;code&gt;.docx&lt;/code&gt;, or &lt;code&gt;.html&lt;/code&gt; file should appear in the dropdown. Click each option in turn and confirm the desired result was produced.&lt;/p&gt;

&lt;p&gt;Workspace setup is now complete and mdEditor is ready to use.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;NOTE: The &lt;code&gt;syntax.md&lt;/code&gt; file in the &lt;code&gt;styles&lt;/code&gt; folder contains a detailed description of the linting rules available within the editor workspace. Any rule can be toggled on/off by editing the &lt;code&gt;.markdownlint.json&lt;/code&gt; file using this syntax. &lt;code&gt;"ruleID" : bool&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Happy markdown'ing! :)&lt;/p&gt;

&lt;p&gt;Don't forget to 💖 this article and leave a 💭. If you're feeling extra generous, please click my name below to 🎆subscribe🎇!&lt;/p&gt;

&lt;p&gt;-- killshot13&lt;/p&gt;




&lt;div class="ltag__user ltag__user__id__497515"&gt;
    &lt;a href="/killshot13" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&gt;
        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F497515%2F9113bec9-139f-4100-8f2f-1affcd01fd28.jpg" alt="killshot13 image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/killshot13"&gt;Michael R.&lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/killshot13"&gt;Full-Stack Web Developer— Websites · Web Applications · WordPress · SEO · MongoDB · UGA/GA4 Certified · Windows Insider · WP Core · Ethical Hacker · USAF Veteran&lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;






&lt;h2&gt;
  
  
  Credits &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Extensive credit is owed to &lt;a href="https://twitter.com/thisDaveJ" rel="noopener noreferrer"&gt;Dave&lt;/a&gt; for indirectly inspiring me to create mdEditor after reading &lt;a href="https://thisdavej.com/build-an-amazing-markdown-editor-using-visual-studio-code-and-pandoc/" rel="noopener noreferrer"&gt;this guide&lt;/a&gt; he authored.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/killshot13/mdEditor" rel="noopener noreferrer"&gt;mdEditor&lt;/a&gt; is free software released under the &lt;a href="https://github.com/killshot13/mdEditor/blob/main/LICENSE" rel="noopener noreferrer"&gt;MIT license&lt;/a&gt;. Copyright 2020-2021 Michael Rehnert&lt;/p&gt;

&lt;p&gt;All software programs, extensions, plugins, and digital content referenced and/or used in the documentation and/or installation guide of mdEditor is the respective intellectual property of the creators, developers, and owners thereof and is entitled to the protections granted under U.S. Copyright law.&lt;/p&gt;

</description>
      <category>markdown</category>
      <category>news</category>
      <category>opensource</category>
      <category>showdev</category>
    </item>
    <item>
      <title>The 50,000px Rule: or, Minimum Sizing for High-Resolution Web Images</title>
      <dc:creator>Michael R.</dc:creator>
      <pubDate>Mon, 31 May 2021 13:04:00 +0000</pubDate>
      <link>https://dev.to/killshot13/the-50-000px-rule-minimum-sizing-for-high-resolution-web-images-3h5a</link>
      <guid>https://dev.to/killshot13/the-50-000px-rule-minimum-sizing-for-high-resolution-web-images-3h5a</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;Today, like most other days in any given month, I learned something new. But this tidbit of knowledge was particularly intriguing and, in my experience, not something that is well-known among web devs and SEO experts. &lt;/p&gt;

&lt;p&gt;So I thought to myself, on the off chance that I haven't been living under a rock this whole time, why not pen a short piece and spread the word? &lt;/p&gt;

&lt;p&gt;Hopefully, by now, I've piqued your curiosity a bit. So without further ado, let's explore what I have christened, the 50,000px Rule. &lt;/p&gt;

&lt;h3&gt;
  
  
  High-Level Overview
&lt;/h3&gt;

&lt;p&gt;I recently became aware of this information while completing a &lt;a href="https://codelabs.developers.google.com/" rel="noopener noreferrer"&gt;Google Codelab&lt;/a&gt; on JSON-LD structured data. While a bit off-topic from my objective, some of the related verbiages caught my attention. Let's have a look! &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"For best results, provide multiple high-resolution images (minimum of 50K pixels when multiplying width and height) with the following aspect ratios: 16x9, 4x3, and 1x1."&lt;/em&gt; &lt;br&gt;
--&lt;a href="https://developers.google.com/search/docs/data-types/recipe?authuser=1#recipe-properties" rel="noopener noreferrer"&gt;Google Search Central&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So basically, what Google is trying to say here is this. If this expression doesn't return true after plugging in the dimensions of your photos, then your site isn't serving high-resolution imagery. &lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;span&amp;gt;imgW * imgL &amp;amp;gt;= sqrt(50,000)&amp;lt;/span&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Let's simplify the math just a tad. We know that (2 x2 =4), so let's assign these values to a simple square.  Using the formula for a given square area, we can determine a 2in x2in square has a surface area of...surprise! Four square inches. &lt;/p&gt;




&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4mqbpb6wo47181abydhs.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4mqbpb6wo47181abydhs.jpg" alt="oh-no-not-math-startled-cat" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Now we must realize this calculation does not change based on the unit of measurement. If we instead had a 2-foot square or a 2-cm square, the unit of measure being used won't alter the actual values. &lt;/p&gt;

&lt;p&gt;So then, is a pixel also a unit of measure? Of course! Pixels, abbreviated as "px," are a tiny unit of measure; one pixel is about 1⁄96 inch (0.26 mm). &lt;/p&gt;

&lt;p&gt;While small, these specks do play an essential role in web design. Pixels are used to make sure a given element will render no matter what screen resolution is used for viewing. &lt;/p&gt;

&lt;h3&gt;
  
  
  Practical Application
&lt;/h3&gt;

&lt;p&gt;Getting back to the 50,000px Rule, we should find the concept seems much simpler now. To meet the minimum requirements for a  high-resolution image, a photograph just needs to have a square area of at least 50K pixels. &lt;/p&gt;

&lt;p&gt;Let's calculate what this means using three aspect ratios widely recommended as variants of any image we might serve on a webpage.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1:1 - the basic square or thumbnail image&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We should be familiar by now with this type of calculation. After taking the square root of 50,000, we discover the minimum size for a high-resolution photo with a 1:1 ratio. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxy31440930kyq6u43jbb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxy31440930kyq6u43jbb.png" alt="244x244px" width="224" height="224"&gt;&lt;/a&gt;1:1 aspect ratio &lt;/p&gt;




&lt;ul&gt;
&lt;li&gt;4:3 - the nostalgic "&lt;a href="https://nofilmschool.com/2018/10/creative-weight-43-aspect-ratio" rel="noopener noreferrer"&gt;Academy ratio&lt;/a&gt;" used in older films&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once the shape changes from a square to a rectangle, the calculation process becomes less granular and involves ratios and fractions. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foal3mnzoshl83atypjx0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foal3mnzoshl83atypjx0.png" alt="260x195px" width="260" height="195"&gt;&lt;/a&gt;4:3 aspect ratio &lt;/p&gt;




&lt;ul&gt;
&lt;li&gt;16:9 - the current "widescreen" cinematic standard&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As you might assume, the larger the base ratio, the larger the gap between 50,000 and the actual size of our image. With a 16:9 aspect ratio, we cannot get closer than 51,984 square pixels without using decimal numbers. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffhojuzzc8oxvvrcnew3m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffhojuzzc8oxvvrcnew3m.png" alt="340x171px" width="304" height="171"&gt;&lt;/a&gt;16:9 aspect ratio &lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;So there you have it, folks, the 50,000 Rule demystified. Now I do not anticipate any developer, not even myself, will need to reference this information very often. &lt;/p&gt;

&lt;p&gt;Still, it was fun to research and it also sets a concrete baseline for high-resolution imagery. I hope that you enjoyed reading this article and perhaps you have also learned something new today! &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"For an image to be considered high-resolution when served on the Web, it must satisfy the 50,000px Rule."&lt;/em&gt; &lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;Don't forget to 💖 this article and leave a 💭; I look forward to reading your thoughts and opinions in the comments below. If you're feeling extra generous, please click my name below to 🎆subscribe🎇! &lt;/p&gt;

&lt;p&gt;-- killshot13&lt;/p&gt;


&lt;div class="ltag__user ltag__user__id__497515"&gt;
    &lt;a href="/killshot13" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&gt;
        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F497515%2F9113bec9-139f-4100-8f2f-1affcd01fd28.jpg" alt="killshot13 image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/killshot13"&gt;Michael R.&lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/killshot13"&gt;Full-Stack Web Developer— Websites · Web Applications · WordPress · SEO · MongoDB · UGA/GA4 Certified · Windows Insider · WP Core · Ethical Hacker · USAF Veteran&lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;


</description>
      <category>webdev</category>
      <category>design</category>
      <category>performance</category>
      <category>ux</category>
    </item>
    <item>
      <title>What is Pandoc?</title>
      <dc:creator>Michael R.</dc:creator>
      <pubDate>Fri, 07 May 2021 11:04:16 +0000</pubDate>
      <link>https://dev.to/killshot13/what-is-pandoc-1hbc</link>
      <guid>https://dev.to/killshot13/what-is-pandoc-1hbc</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Cover Image Credit: &lt;em&gt;&lt;a href="https://groups.google.com/g/pandoc-discuss/c/1bKIuyBnWaQ/discussion" rel="noopener noreferrer"&gt;RFC: Designing Logo of Pandoc&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Most developers have probably wondered or even asked the question at some point, "What exactly is &lt;a href="http://pandoc.org/installing.html" rel="noopener noreferrer"&gt;Pandoc&lt;/a&gt;?" or "What do people use Pandoc for?"&lt;/p&gt;

&lt;p&gt;I certainly did! So, I have written a short article to help answer that question. Much of the information in this article is sourced from &lt;a href="https://gist.github.com/killshot13/5b379355d275e79a5cb1f03c841c7d53" rel="noopener noreferrer"&gt;a gist I had put together&lt;/a&gt; over the course of several months.&lt;/p&gt;





&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;





&lt;p&gt;Defined as a universal &lt;a href="https://en.wikipedia.org/w/index.php?title=Pandoc&amp;amp;oldid=1018572588" rel="noopener noreferrer"&gt;document converter&lt;/a&gt;, Pandoc is an open-source software program for file conversion. Pandoc is not a markup language, nor is it a CLI, although it is used from one. 🙃&lt;/p&gt;

&lt;p&gt;If you need to convert files from any conceivable format to another, Pandoc is your best friend. It has become popular across multiple industry and technology sectors. &lt;/p&gt;

&lt;p&gt;The value of Pandoc shines brightest when used to transform file types like Markdown, Microsoft Word (.docx), and XML into more user-friendly documents and markup languages, including PDF and HTML.&lt;/p&gt;




&lt;h2&gt;
  
  
  Installing Pandoc
&lt;/h2&gt;

&lt;p&gt;I will assume at this point, if you are still reading, you likely want to try Pandoc out for yourself.&lt;/p&gt;

&lt;p&gt;Listed below are the steps I took to install and configure Pandoc on Windows (10 Pro Edition) and Linux (Ubuntu 20.04 Focal) for Markdown to PDF document conversion.&lt;/p&gt;

&lt;p&gt;Please note all disclaimers remain flapping in the breeze. Pandoc is open-source software that carries no warranty of any kind. Likewise, I make no guarantee that you will achieve a favorable result simply by following the steps below. 🙃&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Your Mileage Might Vary&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  --&amp;gt; Pandoc on Windows
&lt;/h3&gt;

&lt;p&gt;I have been using the &lt;a href="https://community.chocolatey.org/" rel="noopener noreferrer"&gt;Chocolately&lt;/a&gt; package manager for Windows for several years now. So for me, the simplest way to get Pandoc up and running was first to install it with this command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;choco &lt;span class="nb"&gt;install &lt;/span&gt;pandoc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Then I grabbed the Windows installer for MikTex (one of many Pandoc engines) from the &lt;a href="https://miktex.org/download" rel="noopener noreferrer"&gt;official downloads page&lt;/a&gt; and ran the &lt;code&gt;.exe&lt;/code&gt; file to install.&lt;/p&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff2h5leq7n045ucq11kgp.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff2h5leq7n045ucq11kgp.jpg" alt="markdown-to-pdf-pandoc-sample" width="800" height="436"&gt;&lt;/a&gt;Before-and-after view when running the markdown-to-pdf command in Pandoc &lt;/p&gt;

&lt;p&gt;No further configuration was necessary, at least not from a functional point of view. However, Pandoc will let you customize certain behaviors at quite a granular level.&lt;/p&gt;

&lt;p&gt;There is a &lt;a href="https://dev.to/killshot13/what-is-pandoc-1hbc#configuring-pandoc"&gt;configuration section&lt;/a&gt; toward the end of this article offers a good starting place for those wishing to take a deeper dive.&lt;/p&gt;


&lt;h3&gt;
  
  
  --&amp;gt; Pandoc on Linux
&lt;/h3&gt;

&lt;p&gt;Getting Pandoc setup with &lt;code&gt;.pdf&lt;/code&gt; capabilities on Linux proved a bit more challenging.&lt;/p&gt;

&lt;p&gt;After navigating a good deal of noise encountered while researching different packages, I found &lt;a href="https://askubuntu.com/a/1219144/1153800" rel="noopener noreferrer"&gt;the consensus&lt;/a&gt; seemed to favor a Pandoc/TexLive setup.&lt;/p&gt;

&lt;p&gt;Since I am running Ubuntu Linux on WSL2, I opted to build from scratch to avoid conflicts with my local Windows environment.&lt;/p&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpexrjudjth3ixhwq0bq7.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpexrjudjth3ixhwq0bq7.jpg" alt="markdown-to-html-pandoc.jpg" width="800" height="424"&gt;&lt;/a&gt;Before-and-after view when running the markdown-to-html command in Pandoc &lt;/p&gt;



&lt;p&gt;First, I pulled the latest tarball from the &lt;a href="https://github.com/jgm/pandoc/releases/" rel="noopener noreferrer"&gt;release page&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;There are multiple assets available with each release, so check your OS architecture first rather than blindly copying the snippets. This way, you can ensure you are requesting the correct package for your machine.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;wget https://github.com/jgm/pandoc/releases/download/2.13/pandoc-2.13-linux-amd64.tar.gz
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Then, without switching directories, I used a two-step installation process.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo tar &lt;/span&gt;xvzf &lt;span class="nv"&gt;$TGZ&lt;/span&gt; &lt;span class="nt"&gt;--strip-components&lt;/span&gt; 1 &lt;span class="nt"&gt;-C&lt;/span&gt; &lt;span class="s1"&gt;'/usr/local'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Note that $TGZ and the destination folder in the snippet above are generic, and substitutions must be made to reflect your home directory.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install &lt;/span&gt;texlive texlive-latex-extra
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;And with that, Pandoc was installed on Linux to convert markdown files to PDF documents!&lt;/p&gt;


&lt;h2&gt;
  
  
  Configuring Pandoc
&lt;/h2&gt;

&lt;p&gt;These configuration options are just examples and may not apply in every situation.&lt;/p&gt;

&lt;p&gt;One should always consult the &lt;a href="https://pandoc.org/MANUAL.html" rel="noopener noreferrer"&gt;official Pandoc documentation&lt;/a&gt; for complete details and the latest changes.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nt"&gt;--pdf-engine&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;PROGRAM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Specifies which engine Pandoc should use when producing PDF output.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Valid values are pdflatex, lualatex, xelatex, latexmk, tectonic, wkhtmltopdf, weasyprint, prince, context, and pdfroff.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If the engine is not in your PATH, you can specify the full path of the engine here.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If this option is not specified, pandoc uses the following defaults depending on the output format specified.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;-t&lt;/span&gt; latex or none
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;defaults to pdflatex (other options: xelatex, lualatex, tectonic, latexmk)
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;-t&lt;/span&gt; context:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;defaults to context
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;-t&lt;/span&gt; html:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;defaults to wkhtmltopdf (other options: prince, weasyprint; visit &lt;a href="https://print-css.rocks/" rel="noopener noreferrer"&gt;Print-CSS&lt;/a&gt; for a good introduction to PDF generation from HTML/CSS.)
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;-t&lt;/span&gt; ms:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;defaults to pdfroff&lt;/li&gt;
&lt;/ul&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8nk2jw6wrh63f1k3jgth.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8nk2jw6wrh63f1k3jgth.jpg" alt="markdown-rendered-as-html-pandoc.jpg" width="800" height="533"&gt;&lt;/a&gt;Pandoc can even apply custom styling when rendering HTML from Markdown &lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nt"&gt;--pdf-engine-opt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;STRING
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Use the given string as a command-line argument to the pdf-engine. For example, to use a persistent directory &lt;code&gt;foo&lt;/code&gt; for &lt;a href="https://ctan.org/pkg/latexmk/" rel="noopener noreferrer"&gt;Latexmk&lt;/a&gt;’s auxiliary files, use &lt;code&gt;--pdf-engine-opt=-outdir=foo&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Note that no check for duplicate options is done.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  Credit: &lt;em&gt;&lt;a href="https://pandoc.org/MANUAL.html" rel="noopener noreferrer"&gt;Pandoc User's Guide&lt;/a&gt;&lt;/em&gt;
&lt;/h4&gt;


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

&lt;p&gt;On a related note, if you find yourself working with markdown, HTML, PDF, or XML files quite often, you should check out a little project of mine called mdEditor for VS Code.&lt;/p&gt;

&lt;p&gt;The frameworks installed by mdEditor automate the configurations we just covered in such detail. Now you can generate file conversion with a simple key-binding or click in the command palette!&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/killshot13" rel="noopener noreferrer"&gt;
        killshot13
      &lt;/a&gt; / &lt;a href="https://github.com/killshot13/mdEditor" rel="noopener noreferrer"&gt;
        mdEditor
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Awesome markdown editor for VS Code. Supports linting and prints to HTML, PDF, and MS Word (Docx)!
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;I hope you have found this tutorial useful, and thank you for taking the time to follow along!&lt;/p&gt;

&lt;p&gt;Don't forget to 💖 this article and leave a 💭. If you're feeling extra generous, please click my name below to 🎆subscribe🎇!&lt;/p&gt;

&lt;p&gt;-- killshot13&lt;/p&gt;


&lt;div class="ltag__user ltag__user__id__497515"&gt;
    &lt;a href="/killshot13" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&gt;
        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F497515%2F9113bec9-139f-4100-8f2f-1affcd01fd28.jpg" alt="killshot13 image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/killshot13"&gt;Michael R.&lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/killshot13"&gt;Full-Stack Web Developer— Websites · Web Applications · WordPress · SEO · MongoDB · UGA/GA4 Certified · Windows Insider · WP Core · Ethical Hacker · USAF Veteran&lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;





&lt;p&gt;&lt;strong&gt;A Note on Pandoc&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Copyright 2006–2021 &lt;a href="mailto:jgm@berkeley.edu"&gt;John MacFarlane&lt;/a&gt;. Released under the &lt;a href="https://www.gnu.org/copyleft/gpl.html" rel="noopener noreferrer"&gt;GPL&lt;/a&gt;, version 2 or greater. This software carries no warranty of any kind. (See COPYRIGHT for full copyright and warranty notices.) For a full list of contributors, see the file AUTHORS.md in the &lt;a href="https://github.com/jgm/pandoc" rel="noopener noreferrer"&gt;Pandoc source code&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>markdown</category>
      <category>productivity</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Pure CSS Blockquotes</title>
      <dc:creator>Michael R.</dc:creator>
      <pubDate>Mon, 29 Mar 2021 01:34:49 +0000</pubDate>
      <link>https://dev.to/killshot13/pure-css-blockquotes-2l2e</link>
      <guid>https://dev.to/killshot13/pure-css-blockquotes-2l2e</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;Developed using only CSS and HTML, these blockquotes examples offer a nice way to show off your site's accent color(s) without much extra work.&lt;/p&gt;

&lt;p&gt;By using the natural breakpoints in the &lt;code&gt;border&lt;/code&gt; and changing the &lt;code&gt;width&lt;/code&gt; of the "negative space", I was able to create two nice angled versions. &lt;/p&gt;




&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/killshot13/embed/MWJeOwE?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  But How?
&lt;/h2&gt;

&lt;p&gt;This is made possible by giving &lt;code&gt;border-bottom&lt;/code&gt; and &lt;code&gt;border-top&lt;/code&gt; the exact same color as &lt;code&gt;background-color&lt;/code&gt;, creating a simulated angle that would otherwise be hard to achieve on such a narrow width.&lt;/p&gt;

&lt;p&gt;I'm sure I cannot be the only one to have thought of this idea, but I have not yet come across it so I am quite proud to take credit for this version of the concept at least. 🙃🙃🙃&lt;/p&gt;

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

&lt;p&gt;Of course, anyone is free to use it or find ways to improve it. Just put a link back in the comments, please!&lt;/p&gt;

&lt;p&gt;Don't forget to 💖 this article and/or leave a 💭. Even better, you can click my name below to 🎆subscribe🎇! &lt;/p&gt;

&lt;p&gt;Until next time...&lt;/p&gt;

&lt;p&gt;-- killshot13&lt;/p&gt;





&lt;div class="ltag__user ltag__user__id__497515"&gt;
    &lt;a href="/killshot13" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&gt;
        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F497515%2F9113bec9-139f-4100-8f2f-1affcd01fd28.jpg" alt="killshot13 image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/killshot13"&gt;Michael R.&lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/killshot13"&gt;Full-Stack Web Developer— Websites · Web Applications · WordPress · SEO · MongoDB · UGA/GA4 Certified · Windows Insider · WP Core · Ethical Hacker · USAF Veteran&lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;





</description>
      <category>codepen</category>
      <category>css</category>
      <category>html</category>
    </item>
    <item>
      <title>New WordPress Admin Color Palette</title>
      <dc:creator>Michael R.</dc:creator>
      <pubDate>Thu, 18 Mar 2021 12:42:56 +0000</pubDate>
      <link>https://dev.to/killshot13/new-wordpress-admin-color-palette-1001</link>
      <guid>https://dev.to/killshot13/new-wordpress-admin-color-palette-1001</guid>
      <description>&lt;h4&gt;
  
  
  &lt;strong&gt;WOW!&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;So pretty...&lt;/p&gt;

&lt;p&gt;Let me just say I am loving this brand-new color palette repository for WordPress! (core, .org, and related projects) &lt;/p&gt;

&lt;p&gt;Oh, and if you're a WP plugin developer, listen up because this applies to you too. And you'll also want to grab &lt;a href="https://gist.github.com/ryelle/ce466fe20e9c8165d8cafe9597b84316" rel="noopener noreferrer"&gt;this handy PostCSS tool&lt;/a&gt; to automate your CSS changes courtesy of &lt;a href="https://profiles.wordpress.org/ryelle/" rel="noopener noreferrer"&gt;@ryelle&lt;/a&gt;! 😁😎&lt;/p&gt;

&lt;p&gt;In his February post, &lt;a href="https://make.wordpress.org/core/2021/02/23/standardization-of-wp-admin-colors-in-wordpress-5-7/" rel="noopener noreferrer"&gt;Standardization of WP-Admin colors in WordPress 5.7&lt;/a&gt;, WP Core dev &lt;a href="https://profiles.wordpress.org/audrasjb/" rel="noopener noreferrer"&gt;Jb Audras&lt;/a&gt; offered the following in-depth summary, and I quote:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;This is the first part of a larger project in cleaning up WordPress admin CSS. In WordPress 5.7, all colors used in the CSS are collapsed to one of 12 blues, greens, reds, and yellows, 13 grays, pure black, and pure white.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This new streamlined color palette collapses all the colors that used to be in the WordPress source code down to seven core colors and a range of 56 shades that meet the WCAG 2.0 AA recommended contrast ratio against white or black.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The colors are perceptually uniform from light to dark in each range, which means they start at white and get darker by the same amount with each step. Half the range has a 4.5 or higher contrast ratio against black, and the other half maintains the same contrast against white.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Standardizing on this set of colors will help contributors make consistent, accessible design decisions. Themes and Plugin developers are encouraged to use this new color palette for better consistency between their products and WordPress Core.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Plugin authors that use the existing CSS Core classes should be all set up with the new color palette, as every Core class was updated accordingly.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Need/want more details? Check out the official &lt;a href="https://make.wordpress.org/design/handbook/foundations/colors" rel="noopener noreferrer"&gt;Design Handbook&lt;/a&gt; or the CodePen palette shown below.&lt;/p&gt;




&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/ryelle/embed/WNGVEjw?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Now for a quick recruitment pitch&lt;/em&gt; 😅&lt;/p&gt;

&lt;p&gt;Did you know that anyone is welcome to come and help shape future upgrades and improvements to WordPress? True open-source to the core, there are no prerequisites to joining the WordPress community.&lt;/p&gt;

&lt;p&gt;It's also an excellent opportunity for those of us starting out as developers and designers to join a thriving open-source community and gain some valuable experience.&lt;/p&gt;

&lt;p&gt;Interested? Consider contributing just 5% of your overall development time/effort by joining us in the &lt;a href="https://wordpress.org/five-for-the-future/" rel="noopener noreferrer"&gt;Five for the Future&lt;/a&gt; initiative!&lt;/p&gt;

&lt;p&gt;You will have the opportunity to help develop the subsequent versions of WordPress in countless ways, from casually providing feedback to working directly with the elite WP Core team.&lt;/p&gt;




&lt;p&gt;Don't forget to 💖 this article and leave a 💭. If you're feeling extra generous, please click my name below to 🎆subscribe🎇!&lt;/p&gt;

&lt;p&gt;-- killshot13&lt;/p&gt;





&lt;div class="ltag__user ltag__user__id__497515"&gt;
    &lt;a href="/killshot13" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&gt;
        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F497515%2F9113bec9-139f-4100-8f2f-1affcd01fd28.jpg" alt="killshot13 image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/killshot13"&gt;Michael R.&lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/killshot13"&gt;Full-Stack Web Developer— Websites · Web Applications · WordPress · SEO · MongoDB · UGA/GA4 Certified · Windows Insider · WP Core · Ethical Hacker · USAF Veteran&lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;





</description>
      <category>codepen</category>
      <category>ux</category>
      <category>wordpress</category>
    </item>
    <item>
      <title>"Discussions"</title>
      <dc:creator>Michael R.</dc:creator>
      <pubDate>Wed, 17 Mar 2021 20:17:34 +0000</pubDate>
      <link>https://dev.to/killshot13/discussions-1n5b</link>
      <guid>https://dev.to/killshot13/discussions-1n5b</guid>
      <description>&lt;h4&gt;
  
  
  &lt;strong&gt;A THOROUGH REVIEW OF GITHUB'S LATEST BRAINCHILD&lt;/strong&gt;
&lt;/h4&gt;




&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;After nearly a year of private beta testing, GitHub confirmed last month in a blog post that its new &lt;a href="https://docs.github.com/en/discussions" rel="noopener noreferrer"&gt;Discussions&lt;/a&gt; feature is now available as a public beta.&lt;/p&gt;

&lt;p&gt;First revealed during the live stream of GitHub's &lt;a href="https://githubsatellite.com/" rel="noopener noreferrer"&gt;Satellite Virtual 2020&lt;/a&gt;, this latest addition to the GitHub platform seeks to provide a way for software communities to collaborate outside the codebase.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3oud35r5wy6wjbrwoe7v.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3oud35r5wy6wjbrwoe7v.jpeg" alt="View of a " width="800" height="502"&gt;&lt;/a&gt;View of a "GitHub Discussion" &lt;/p&gt;




&lt;p&gt;In theory, the new feature will improve collective participation for open-source projects while smoothing communication lines between project managers, developers, beta testers, and end-users.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Discussions is a collaborative communication forum for the community around an open-source project."&lt;/em&gt; — &lt;a href="https://docs.github.com/en/discussions" rel="noopener noreferrer"&gt;GitHub Docs&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Some prominent repositories, such as &lt;a href="https://github.com/nodejs/node/discussions" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt;, &lt;a href="https://github.com/laravel/framework/discussions" rel="noopener noreferrer"&gt;Laravel&lt;/a&gt;, &lt;a href="https://github.com/vercel/next.js/discussions" rel="noopener noreferrer"&gt;Next.js&lt;/a&gt;, and &lt;a href="https://github.com/prisma/prisma/discussions" rel="noopener noreferrer"&gt;Prisma&lt;/a&gt;, participated in the first round of beta testing and have already successfully integrated Discussions. Based on current trends, &lt;strong&gt;it appears that Discussions is poised to reshape the existing structure of most GitHub repositories&lt;/strong&gt;.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://github.com/vercel/next.js/discussions" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp57qxyax6vzculdnu5th.jpeg" alt="A view of " width="800" height="743"&gt;&lt;/a&gt;&lt;a href="https://github.com/vercel/next.js/discussions" rel="noopener noreferrer"&gt;View of a "GitHub Discussion"&lt;/a&gt; &lt;/p&gt;




&lt;h2&gt;
  
  
  Features
&lt;/h2&gt;

&lt;p&gt;By default, &lt;strong&gt;four categories&lt;/strong&gt; are created to help Discussions stay organized.&lt;/p&gt;

&lt;blockquote&gt;
&lt;ol&gt;
&lt;li&gt;💬 General&lt;/li&gt;
&lt;li&gt;💡 Idea&lt;/li&gt;
&lt;li&gt;🙏 Q&amp;amp;A&lt;/li&gt;
&lt;li&gt;🙌 Show and tell&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;

&lt;p&gt;Aside from these templated options, repository owners can author unlimited custom threads. &lt;strong&gt;Users are encouraged to mark quality answers as helpful&lt;/strong&gt;, similar to the familiar layout of Stack Overflow.&lt;/p&gt;

&lt;p&gt;Discussions also attempts to establish content moderation by &lt;strong&gt;allowing top contributors to achieve higher privileges&lt;/strong&gt;. This option should help relieve some stress for the developer(s), who would otherwise be forced to keep a constant eye on the conversations.&lt;/p&gt;




&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/DbTWBP3_RbM"&gt;
&lt;/iframe&gt;Video provided courtesy of &lt;a href="https://www.youtube.com/channel/UC7c3Kb6jYCRj4JO" rel="noopener noreferrer"&gt;Github&lt;/a&gt; and &lt;a href="https://www.mishmanners.com/" rel="noopener noreferrer"&gt;Michelle Mannering&lt;/a&gt;
 &lt;/p&gt;


&lt;h2&gt;
  
  
  Configuration
&lt;/h2&gt;

&lt;p&gt;Anyone can configure Discussions quite easily; it took me about &lt;strong&gt;5–10 minutes per repository&lt;/strong&gt; on average.&lt;/p&gt;

&lt;p&gt;The layout is almost identical to GitHub issues, allowing for creating any number of topics linked to a single repository, each with a unique title and URL. While this is conducive in most scenarios, the setup could intimidate some developers who maintain an extensive library of source code.&lt;/p&gt;

&lt;p&gt;Fortunately, &lt;strong&gt;most of the configuration is already provided by a boilerplate template&lt;/strong&gt;. I found the default options to be well-balanced, sparing precious design time while still allowing customization.&lt;/p&gt;



&lt;p&gt;&lt;a href="https://docs.github.com/en/discussions/quickstart" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiayo2uvy9x6l4top9lp4.jpeg" alt="Getting Started with Discussions" width="800" height="777"&gt;&lt;/a&gt;&lt;a href="https://docs.github.com/en/discussions/quickstart" rel="noopener noreferrer"&gt;Getting Started with Discussions&lt;/a&gt; &lt;/p&gt;



&lt;p&gt;As shown above, the option to enable Discussions is now available for every repository. To access, open the settings tab and scroll to the bottom of the features section.&lt;/p&gt;

&lt;p&gt;You are now presented with a template containing several options to personalize if you so desire. Styling with Markdown is supported, so once you are satisfied, preview and publish just like a &lt;code&gt;README&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A new menu tab should appear in the navbar of the repository. Here, members of the software community who utilize your code can now gather to converse and collaborate.&lt;/p&gt;


&lt;h2&gt;
  
  
  Outlook
&lt;/h2&gt;

&lt;p&gt;Some developers contend that Discussions shares too much similarity with existing features to be worth the hassle. Others fear that management will pile more expectations onto an already overwhelming workload.&lt;/p&gt;

&lt;p&gt;As it stands, Discussions admittedly leaves room for improvement and likely will not be suitable for every situation. That being said, the latest metrics released by GitHub in a new report are nothing short of impressive.*&lt;/p&gt;

&lt;p&gt;Since January 2020 —&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;3000 discussions&lt;/strong&gt; have been created.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;50% of active Discussions users&lt;/strong&gt; contributed or pushed code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;34% more pull requests&lt;/strong&gt; were merged.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;18% less time&lt;/strong&gt; was required to accomplish a merge.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;All figures were derived from beta testing conducted after the addition of Discussions to the Next.js repository, which produced a marked overall improvement in &lt;strong&gt;user participation and developer productivity&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;*If you wish to read the entire report, visit &lt;a href="//octoverse.github.com"&gt;octoverse.github.com&lt;/a&gt;, where you can also download a PDF copy for later reference.&lt;/p&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffo3ashle60qa848i1gi4.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffo3ashle60qa848i1gi4.jpeg" alt="Customization options for pinned Discussions" width="800" height="538"&gt;&lt;/a&gt;Customization options for pinned Discussions &lt;/p&gt;


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

&lt;p&gt;Every developer knows that data from a test environment cannot be used conclusively to predict future performance.&lt;/p&gt;

&lt;p&gt;However, if the benchmarks established last year hold steady, we can safely assume that Discussions' popularity and usage will continue to increase across GitHub. So here is my personal opinion on the matter.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Provided as users, we treat Discussions like a tool and not a social media platform; and as project managers, we gradually and tactfully integrate the feature; I believe many benefits can be realized.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I would love to hear perspectives from all of you, so please leave your thoughts in the comments.&lt;/p&gt;

&lt;p&gt;Don't forget to 💖 this article and leave a 💭. If you're feeling extra generous, please click my name below to 🎆subscribe🎇!&lt;/p&gt;

&lt;p&gt;-- killshot13&lt;/p&gt;




&lt;div class="ltag__user ltag__user__id__497515"&gt;
    &lt;a href="/killshot13" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&gt;
        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F497515%2F9113bec9-139f-4100-8f2f-1affcd01fd28.jpg" alt="killshot13 image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/killshot13"&gt;Michael R.&lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/killshot13"&gt;Full-Stack Web Developer— Websites · Web Applications · WordPress · SEO · MongoDB · UGA/GA4 Certified · Windows Insider · WP Core · Ethical Hacker · USAF Veteran&lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;





</description>
      <category>github</category>
      <category>news</category>
      <category>productivity</category>
    </item>
    <item>
      <title>On Winning the Node Badge</title>
      <dc:creator>Michael R.</dc:creator>
      <pubDate>Sat, 06 Mar 2021 20:12:32 +0000</pubDate>
      <link>https://dev.to/killshot13/on-winning-the-node-badge-2m0n</link>
      <guid>https://dev.to/killshot13/on-winning-the-node-badge-2m0n</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Disclaimer: This post contains no technical content.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;I wanted to write a brief post to express my gratitude for the overwhelming success of &lt;a href="https://daily.dev/blog/how-to-build-an-smtp-mail-server-with-express-node-and-gmail" rel="noopener noreferrer"&gt;my latest article&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;A special thanks goes out especially to my new subscribers and fans. I am honored and very grateful to you all. &lt;/p&gt;

&lt;p&gt;To express my appreciation, here's the highlights of what you helped me achieve! &lt;/p&gt;




&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;3x featured&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;50+ retweets&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;200+ reactions&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Over 6,000 views ...and...&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;... 1 Node Badge!&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmdyag4vpdkittzwq1a7z.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmdyag4vpdkittzwq1a7z.jpg" alt="Node Badge" width="800" height="799"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;And to the folks at &lt;a href="https://daily.dev" rel="noopener noreferrer"&gt;daily.dev&lt;/a&gt; and &lt;a href="https://dev.to"&gt;DEV&lt;/a&gt;, thank you for providing the feedback, encouragement, and most of all the infrastructure to make this possible. &lt;/p&gt;

&lt;p&gt;I look forward to writing more quality articles that each of you will enjoy and benefit from. &lt;/p&gt;

&lt;p&gt;Thanks again! 🤗🤗🤗&lt;/p&gt;

&lt;p&gt;-- killshot13&lt;/p&gt;





&lt;div class="ltag__user ltag__user__id__497515"&gt;
    &lt;a href="/killshot13" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&gt;
        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F497515%2F9113bec9-139f-4100-8f2f-1affcd01fd28.jpg" alt="killshot13 image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/killshot13"&gt;Michael R.&lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/killshot13"&gt;Full-Stack Web Developer— Websites · Web Applications · WordPress · SEO · MongoDB · UGA/GA4 Certified · Windows Insider · WP Core · Ethical Hacker · USAF Veteran&lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;





</description>
      <category>discuss</category>
      <category>webdev</category>
      <category>node</category>
    </item>
    <item>
      <title>How To Build an SMTP Mail Server with Express, Node, and Gmail</title>
      <dc:creator>Michael R.</dc:creator>
      <pubDate>Fri, 26 Feb 2021 12:07:36 +0000</pubDate>
      <link>https://dev.to/killshot13/how-to-build-an-smtp-mail-server-with-express-node-and-gmail-aof</link>
      <guid>https://dev.to/killshot13/how-to-build-an-smtp-mail-server-with-express-node-and-gmail-aof</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;Recently I had the opportunity to develop and integrate an SMTP Email Server into a more extensive full-stack application. Today we will reference the code from my solution for this tutorial. &lt;/p&gt;

&lt;p&gt;We'll primarily be using Express and Node to create this server. We’ll also integrate Nodemailer to construct a mailable object and Gmail SMTP Server to deliver our emails free of charge.&lt;/p&gt;

&lt;p&gt;The complete codebase can be viewed here:&lt;/p&gt;





&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--i3JOwpme--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/killshot13"&gt;
        killshot13
      &lt;/a&gt; / &lt;a href="https://github.com/killshot13/express-smtp-mailer"&gt;
        express-smtp-mailer
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A production-ready Node backend with an Express SMTP mail server configurable for use with contact forms, subscriptions, etc.
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;





&lt;h2&gt;
  
  
  Features
&lt;/h2&gt;

&lt;p&gt;Before we start coding, we should quantify the expected functionality of our Express mail server. We can always refer back to this list later if confusion develops.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Establish API routes&lt;/em&gt; to a contact form on the frontend.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Receive user data&lt;/em&gt; from these routes upon form submission.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Format a mailable JSON object&lt;/em&gt; with the data received.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Construct a transport function&lt;/em&gt; with Nodemailer in preparation for delivery.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Obtain authorization&lt;/em&gt; from Gmail using credentials stored in the server.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Call the transport function&lt;/em&gt;, prompting Nodemailer to hand off the email object to the Gmail SMTP Server for delivery.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Request confirmation&lt;/em&gt; of successful delivery and return an error message if not received.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Upon completion, we will have the perfect backend for processing contact forms. Alternatively, our server will also provide a solid base to build a full-stack MERN app with plenty of functionality.&lt;/p&gt;

&lt;p&gt;The production version of the server we are building today powers the backend of &lt;a href="https://ormica.com"&gt;Ormica&lt;/a&gt;, a real estate investment firm in S. Florida.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--o0jQDtd5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/6lgbz7trbzbw34ris8jb.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--o0jQDtd5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/6lgbz7trbzbw34ris8jb.jpg" alt="Screenshot of the source code on GitHub"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A basic understanding of fundamental programming concepts and familiarity with at least one server-side programming language such as [&lt;code&gt;Node&lt;/code&gt;, &lt;code&gt;Python&lt;/code&gt;, &lt;code&gt;Ruby&lt;/code&gt;, &lt;code&gt;PHP&lt;/code&gt;].&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A code editor such as &lt;a href="https://code.visualstudio.com/"&gt;Visual Studio&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://nodejs.org/en/download"&gt;Node.js&lt;/a&gt; and &lt;a href="https://www.npmjs.com/get-npm"&gt;npm&lt;/a&gt; locally installed. (Current LTS version preferred)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Some developers, including myself, prefer to use &lt;a href="https://github.com/nvm-sh/nvm"&gt;nvm&lt;/a&gt; or &lt;a href="https://github.com/coreybutler/nvm-windows"&gt;nvm-windows&lt;/a&gt; to simplify Node version management, which is perfectly fine.&lt;/p&gt;

&lt;p&gt;For further reference, you can check out also &lt;a href="https://daily.dev/posts/how-to-use-multiple-node-versions-with-nvm-on-macos-node-version-manager"&gt;How To Use Multiple Node Versions With NVM On MacOS - Node Version Manager&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Development
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;em&gt;Part 1. Dependencies&lt;/em&gt;
&lt;/h3&gt;

&lt;h4&gt;
  
  
  &lt;em&gt;The moment has arrived! Time to write some code.&lt;/em&gt;
&lt;/h4&gt;

&lt;p&gt;Begin with these terminal commands to make an empty directory wherever you wish to store your server's local version and create the first file using npm.&lt;/p&gt;






&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    &lt;span class="nb"&gt;mkdir &lt;/span&gt;smtp-email-server
    &lt;span class="nb"&gt;cd &lt;/span&gt;smtp-email-server
    npm init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;p&gt;Follow the terminal prompts from npm to create a package.json file. In most cases, the default values will suffice, but be sure to change the entry point to &lt;code&gt;server.js&lt;/code&gt; instead of the proposed &lt;code&gt;index.js&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now we need to add the required dependencies (npm packages) to our project. Run the following command and notice that npm automatically creates a new directory called &lt;code&gt;node_modules&lt;/code&gt;. This is normal, so don't change or configure anything in this folder.&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;express nodemailer morgan dotenv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;p&gt;Let's glance at a brief overview of each package.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Express&lt;/strong&gt; is a minimal and flexible Node.js web application framework that provides a robust set of features.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Nodemailer&lt;/strong&gt; is a module designed to allow Node.js applications to send emails securely and efficiently.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Morgan&lt;/strong&gt; is named after Dexter (a show you should not watch until completion) and provides HTTP request logger middleware for Node.js.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;dotenv&lt;/strong&gt; is a zero-dependency module that loads environment variables from a &lt;code&gt;.env&lt;/code&gt; file into &lt;code&gt;process.env&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;
  
  
  &lt;em&gt;Part 2. Routes&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;Let's begin by creating a &lt;code&gt;routes&lt;/code&gt; folder containing &lt;code&gt;routes.js&lt;/code&gt;.&lt;/p&gt;




&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    &lt;span class="nb"&gt;mkdir &lt;/span&gt;routes &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;routes &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;touch &lt;/span&gt;routes.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;p&gt;Open &lt;code&gt;routes.js&lt;/code&gt; in your code editor and establish a baseline by requiring the dependencies at the top of the file.&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;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;dotenv&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="c1"&gt;// routes.js&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;router&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;express&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;Router&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;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="s2"&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="nx"&gt;nodemailer&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;nodemailer&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;As you can see, Express has its own built-in router. I have opted to use this option instead of a separate npm package. This helps keep our application lightweight and efficient.&lt;/p&gt;

&lt;p&gt;Our next order of work will involve setting up authentication using our Gmail account credentials. Don't forget to add the &lt;code&gt;.env&lt;/code&gt; file in the root directory rather than our current location.&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;transport&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;//this is the authentication for sending email.&lt;/span&gt;
        &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;smtp.gmail.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;465&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;secure&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="c1"&gt;// use TLS&lt;/span&gt;
        &lt;span class="cm"&gt;/* create a .env file and define your credentials. */&lt;/span&gt;
        &lt;span class="na"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&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;SMTP_TO_EMAIL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;pass&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&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;SMTP_TO_PASSWORD&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;Remember the transport function we mentioned earlier? In this step, we will construct that same function. Let's have a look!&lt;/p&gt;




&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="c1"&gt;// call the transport function&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;transporter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;nodemailer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createTransport&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;transport&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;transporter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;verify&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;success&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;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;//if error happened code ends here&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;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&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;//this means success&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;Ready to send mail!&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;Now let's build the API routes. We will simultaneously define the schema for our JSON object (email).&lt;/p&gt;

&lt;p&gt;In simple terms, we are telling Nodemailer about the form data it will be receiving from the front-end and how it should translate said data into a structured email.&lt;/p&gt;

&lt;p&gt;Finally, we call the &lt;code&gt;transporter.sendMail&lt;/code&gt; function, Nodemailer works its magic, and the email goes on its merry way to the recipient's inbox.&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;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&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;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Working&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&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="c1"&gt;//make mailable object&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mail&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&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;SMTP_FROM_EMAIL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&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;SMTP_TO_EMAIL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;subject&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;New Contact Form Submission&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Contact Details:
                   Name: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; 
                   Email: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; 
                   Phone: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tel&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; 
                   Message: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt; 
         &lt;span class="p"&gt;}&lt;/span&gt;
         &lt;span class="nx"&gt;transporter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sendMail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mail&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&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;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
                &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fail&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="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
                &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;success&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="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 last block of code in this file instructs Express to use the routes we have established; finally, we export the entire router to the Node server.&lt;/p&gt;




&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="c1"&gt;// Answer API requests.&lt;/span&gt;
    &lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&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;/api&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="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&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;application/json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;{"message":"Hello from the custom server!"}&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="cm"&gt;/* All remaining requests return the React app, so it can 
    handle routing. */&lt;/span&gt;
    &lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&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;*&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="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&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="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sendFile&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;/react- 
        ui/build&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;index.html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="nx"&gt;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="nx"&gt;router&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;blockquote&gt;
&lt;p&gt;NOTE: &lt;em&gt;If you are unfamiliar with &lt;code&gt;process.env&lt;/code&gt; or merely need a refresher, this Codeburst article provides a splendid reference point.&lt;/em&gt; &lt;/p&gt;
&lt;/blockquote&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="https://codeburst.io/process-env-what-it-is-and-why-when-how-to-use-it-effectively-505d0b2831e7" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QKdWj16a--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/fit/c/96/96/1%2ArwZ45PZOh-Ur7At8fNtGqg%402x.jpeg" alt="Joseph Matthias Goh"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://codeburst.io/process-env-what-it-is-and-why-when-how-to-use-it-effectively-505d0b2831e7" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;process.env: What it is and why/when/how to use it effectively | by Joseph Matthias Goh | codeburst&lt;/h2&gt;
      &lt;h3&gt;Joseph Matthias Goh ・ &lt;time&gt;Jun 20, 2018&lt;/time&gt; ・ 
      &lt;div class="ltag__link__servicename"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ze5yh_2q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/medium_icon-90d5232a5da2369849f285fa499c8005e750a788fdbf34f5844d5f2201aae736.svg" alt="Medium Logo"&gt;
        codeburst.io
      &lt;/div&gt;
    &lt;/h3&gt;
&lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;






&lt;h3&gt;
  
  
  Part 3. &lt;em&gt;Server&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;Let's create a &lt;code&gt;server.js&lt;/code&gt; file in the root directory and open it with the editor.&lt;/p&gt;

&lt;p&gt;Here we are just ensuring everything runs smoothly. I could write an entire article about each of the parameters defined here, but the template is pretty standard. &lt;/p&gt;

&lt;p&gt;Let's start by defining some initial requirements.&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;express&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;express&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;cluster&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;cluster&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;numCPUs&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;os&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;cpus&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;p&gt;Now we should check the environment to see if we are running in production. If so, we use a &lt;a href="https://nodejs.org/api/cluster.html"&gt;cluster of Node processes&lt;/a&gt; to distribute the stress of running the application as evenly as possible across the server cores.&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;isDev&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&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;NODE_ENV&lt;/span&gt; &lt;span class="o"&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="cm"&gt;/* Multi-process to utilize all CPU cores. */&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;isDev&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isMaster&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Node cluster master &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; is running`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
         &lt;span class="c1"&gt;// Fork workers.&lt;/span&gt;
         &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;numCPUs&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
             &lt;span class="nx"&gt;cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fork&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; 
         &lt;span class="p"&gt;}&lt;/span&gt; 
    &lt;span class="nx"&gt;cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;exit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Node cluster worker &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; 
    exited: code &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;, signal &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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;We will then connect to the frontend, priority serve our static HTML files, define some middleware for AJAX parsing, and finally call the routes we are importing from the &lt;code&gt;routes.js&lt;/code&gt; file, all in that order.&lt;/p&gt;

&lt;p&gt;We wrap it up with some error logging for the development environment, and voila! Our Express mail server is humming along.&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;else&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;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;express&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;limiter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;rateLimit&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;windowMs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// 1 minute&lt;/span&gt;
        &lt;span class="na"&gt;max&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&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;morgan&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;morgan&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;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="nx"&gt;PORT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&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;PORT&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;5000&lt;/span&gt;

    &lt;span class="c1"&gt;// apply rate limiter to all requests&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;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;limiter&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;// Priority serve any static files.&lt;/span&gt;
    &lt;span class="c1"&gt;// Replace the example to connect to your frontend.&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;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;static&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;join&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;/example/frontend.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;

    &lt;span class="c1"&gt;// dev middleware&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;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;morgan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dev&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="c1"&gt;// configure body parser for AJAX requests&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;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;urlencoded&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;extended&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&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;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&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;routes&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;./routes/routes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;// after all middleware functions&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;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;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;routes&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;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s2"&gt;`Node &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;
                &lt;span class="nx"&gt;isDev&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dev server&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;cluster 
         worker &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pid&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;: listening on port &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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;&lt;em&gt;SMTP Email Server is complete! Congratulations!&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;NOTE: &lt;em&gt;If you encounter difficulty with the authentication process, read this Google Support documentation! It will save you hours of debugging and Excedrin.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;blockquote class="ltag__twitter-tweet"&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--3fG2wrfR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/1323252806623678465/sOjADzZF_normal.jpg" alt="Michael R profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        Michael R
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        @killsh0t13
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ir1kO05j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      Some well-hidden tips to keep in mind when setting up an SMTP server. I learned the hard way to do better research! 😅&lt;br&gt;&lt;br&gt;&lt;a href="https://t.co/JSwbDjWqSE"&gt;support.google.com/accounts/answe…&lt;/a&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      00:58 AM - 18 Jan 2021
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=1350970875835777026" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fFnoeFxk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-reply-action-238fe0a37991706a6880ed13941c3efd6b371e4aefe288fe8e0db85250708bc4.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=1350970875835777026" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k6dcrOn8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-retweet-action-632c83532a4e7de573c5c08dbb090ee18b348b13e2793175fea914827bc42046.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/like?tweet_id=1350970875835777026" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SRQc9lOp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-like-action-1ea89f4b87c7d37465b0eb78d51fcb7fe6c03a089805d7ea014ba71365be5171.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;



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

&lt;p&gt;We’ve successfully created an SMTP Email Server using Express and Node. We also learned how to integrate Nodemailer and Gmail to streamline the mailing process.&lt;/p&gt;




&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--i3JOwpme--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/killshot13"&gt;
        killshot13
      &lt;/a&gt; / &lt;a href="https://github.com/killshot13/express-smtp-mailer"&gt;
        express-smtp-mailer
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A production-ready Node backend with an Express SMTP mail server configurable for use with contact forms, subscriptions, etc.
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;






&lt;p&gt;Feel free to clone the source code and explore your own methods of implementation. I hope you have found this tutorial useful, and thank you for taking the time to follow along!&lt;/p&gt;

&lt;p&gt;Don't forget to 💖 this article and leave a 💭. If you're feeling extra generous, please click my name below to 🎆subscribe🎇!&lt;/p&gt;

&lt;p&gt;-- killshot13&lt;/p&gt;





&lt;div class="ltag__user ltag__user__id__497515"&gt;
  
    .ltag__user__id__497515 .follow-action-button {
      background-color: #243b4a !important;
      color: #acf4db !important;
      border-color: #243b4a !important;
    }
  
    &lt;a href="/killshot13" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pk5FqWES--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--ltK13tKs--/c_fill%2Cf_auto%2Cfl_progressive%2Ch_150%2Cq_66%2Cw_150/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/497515/a67c9640-5cfc-457a-9e7e-9892cca29900.gif" alt="killshot13 image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/killshot13"&gt;Michael R.&lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/killshot13"&gt;Full-Stack Web Developer— Websites · Web Applications · WordPress · SEO · MongoDB · UGA/GA4 Certified · Windows Insider · WP Core · Ethical Hacker · USAF Veteran&lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;





</description>
      <category>tutorial</category>
      <category>node</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>npm-publish</title>
      <dc:creator>Michael R.</dc:creator>
      <pubDate>Sat, 24 Oct 2020 09:16:25 +0000</pubDate>
      <link>https://dev.to/killshot13/npm-publish-29g1</link>
      <guid>https://dev.to/killshot13/npm-publish-29g1</guid>
      <description>&lt;h2&gt;
  
  
  a guide to releasing your first npm package
&lt;/h2&gt;




&lt;h4&gt;
  
  
  Introduction
&lt;/h4&gt;

&lt;p&gt;npm (node package manager) is the world's largest software registry. According to &lt;a href="https://docs.npmjs.com/about-npm" rel="noopener noreferrer"&gt;the documentation&lt;/a&gt;, npm consists of three distinct components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the registry&lt;/li&gt;
&lt;li&gt;the website&lt;/li&gt;
&lt;li&gt;the CLI&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The registry is an immense database containing all the node packages &amp;amp; modules ever published, complete with version info and metadata.&lt;/p&gt;

&lt;p&gt;On the website, you can search for and view packages, create an npm profile, and manage user settings.&lt;/p&gt;

&lt;p&gt;The CLI provides the primary means of interacting with npm, including the publishing of packages &amp;amp; modules, which we will now cover in-depth.&lt;/p&gt;




&lt;h3&gt;
  
  
  Prerequisites:
&lt;/h3&gt;

&lt;p&gt;(1). an &lt;a href="https://www.npmjs.com" rel="noopener noreferrer"&gt;npm&lt;/a&gt; account&lt;br&gt;
(2). a &lt;a href="https://github.com" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; account&lt;br&gt;
(3). the &lt;a href="https://nodejs.org" rel="noopener noreferrer"&gt;current version&lt;/a&gt; of Node.js&lt;br&gt;
(4). the &lt;a href="https://github.com/npm/cli/releases/latest" rel="noopener noreferrer"&gt;current stable version&lt;/a&gt; of npm&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;npm@latest &lt;span class="nt"&gt;-g&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Package vs Module
&lt;/h3&gt;

&lt;p&gt;It is important to understand the two types of objects you can publish to the registry.&lt;/p&gt;
&lt;h4&gt;
  
  
  How is a package defined?
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;a). A folder containing a program described by a &lt;code&gt;package.json&lt;/code&gt; file.&lt;/li&gt;
&lt;li&gt;b). A g-zipped tarball containing (a).&lt;/li&gt;
&lt;li&gt;c). A URL that resolves to (b).&lt;/li&gt;
&lt;li&gt;d). A &lt;code&gt;&amp;lt;name&amp;gt;@&amp;lt;version&amp;gt;&lt;/code&gt; that is published on the registry with (c).&lt;/li&gt;
&lt;li&gt;e). A &lt;code&gt;&amp;lt;name&amp;gt;@&amp;lt;tag&amp;gt;&lt;/code&gt; that points to (d).&lt;/li&gt;
&lt;li&gt;f). A &lt;code&gt;&amp;lt;name&amp;gt;&lt;/code&gt; that has a &lt;code&gt;latest&lt;/code&gt; tag satisfying (e).&lt;/li&gt;
&lt;li&gt;g). A &lt;code&gt;git&lt;/code&gt; URL that, when cloned, results in (a).&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  How is a module defined?
&lt;/h4&gt;

&lt;p&gt;Any file or directory within &lt;code&gt;node_modules&lt;/code&gt; that can be loaded by the Node.js &lt;code&gt;require()&lt;/code&gt; function. To comply, at least one of these formats must be used.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A folder with a &lt;code&gt;package.json file&lt;/code&gt; containing a &lt;code&gt;"main"&lt;/code&gt; field.&lt;/li&gt;
&lt;li&gt;A folder with an &lt;code&gt;index.js&lt;/code&gt; file in it.&lt;/li&gt;
&lt;li&gt;A JavaScript file.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A module can also be a package, but not all modules are packages by default.&lt;/p&gt;


&lt;h3&gt;
  
  
  Private vs Public
&lt;/h3&gt;

&lt;p&gt;This parameter determines the visibility of your new npm package. For this article, it is assumed that you will elect to create a public package, but you may always reference the &lt;a href="https://docs.npmjs.com/creating-and-publishing-private-packages#publishing-private-packages" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; for more details.&lt;/p&gt;
&lt;h4&gt;
  
  
  Scoped vs Unscoped
&lt;/h4&gt;

&lt;p&gt;Here you will define whether you want to release your code completely to the public domain (unscoped) or publish the code within a retained namespace (scoped).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.npmjs.com/creating-and-publishing-unscoped-public-packages" rel="noopener noreferrer"&gt;Unscoped packages&lt;/a&gt; are always public.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.npmjs.com/about-private-packages" rel="noopener noreferrer"&gt;Private packages&lt;/a&gt; are always scoped.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.npmjs.com/creating-and-publishing-scoped-public-packages" rel="noopener noreferrer"&gt;Scoped packages&lt;/a&gt; are private by default; you must pass a command-line flag when publishing to make them public.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The command line interprets your decision by how your package is named. I'll create examples based on my own npm account username.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    PUBLIC/UNSCOPED: npm publish my-package
    PUBLIC/SCOPED: npm publish @killshot13_npm/my-package &lt;span class="nt"&gt;--access&lt;/span&gt; public
    PRIVATE/SCOPED: npm publish @killshot13_npm/my-package
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;To avoid confusing the reader, I shall refrain from much discussion about teams, organizations, and enterprise accounts. &lt;/p&gt;

&lt;p&gt;Since this article is about publishing our first npm package, I doubt these factors will be of much concern at present. Just be aware of the concepts for future knowledge.&lt;/p&gt;


&lt;h3&gt;
  
  
  Create | Review | Test | Publish
&lt;/h3&gt;

&lt;p&gt;At last, the moment you have been waiting for! These four simple steps are what you will be using to publish your package or module to the registry.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;WARNING: If you deviate from this path or omit one of these steps, chances are you will encounter errors and spend a considerable amount of time debugging your files.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;
  
  
  Create
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    &lt;span class="nb"&gt;mkdir &lt;/span&gt;my-package
    &lt;span class="nb"&gt;cd &lt;/span&gt;my-package
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now that you have a root directory, initiate git and npm.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    git init
    git remote add origin git://YOUR URL HERE
    npm init
    // Follow the prompts to create a package.json file. 
    // Consider the conventions listed above when naming your package.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now open the directory in your favorite code editor and add a &lt;code&gt;README.md&lt;/code&gt; file and the rest of your package code files.&lt;/p&gt;
&lt;h4&gt;
  
  
  Review
&lt;/h4&gt;

&lt;p&gt;In this step, use whatever means are at your disposal to double-check your code for environmental variables, including passwords, API keys, and other sensitive data.&lt;/p&gt;

&lt;p&gt;If necessary, create the appropriate files and replace your existing code with default variables as needed to protect your secrets.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    .gitignore | .npmignore | .env | PROCESS.ENV
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h4&gt;
  
  
  Test
&lt;/h4&gt;

&lt;p&gt;Almost there! Just one more quick (hopefully) thing to wrap up before you publish. To keep bugs out of the registry, especially when publishing publicly, you should first test your package in your own environment.&lt;/p&gt;

&lt;p&gt;Since you are already using the npm CLI, you can just run this command.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    // Use the full path to your project directory.
    npm &lt;span class="nb"&gt;install &lt;/span&gt;my-package
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;If everything functions as designed, congratulations, you are ready to publish your first package!&lt;/p&gt;
&lt;h4&gt;
  
  
  Publish
&lt;/h4&gt;

&lt;p&gt;This is the simplest and most satisfying step. Navigate back to the root directory of your npm package.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    &lt;span class="nb"&gt;cd&lt;/span&gt; /path/to/package
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;em&gt;Are you ready?&lt;/em&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 publish my-package
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;If npm prints something that looks like this, you are golden!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqxvns1m1cm6wwx8se0go.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqxvns1m1cm6wwx8se0go.png" alt="screenshot of successful publish to npm action" width="562" height="373"&gt;&lt;/a&gt;Photo courtesy &lt;a href="https://dev.to/uf4no/npm-behind-the-scenes-and-publish-guide-4gi8"&gt;Dev Community&lt;/a&gt; &lt;/p&gt;


&lt;h3&gt;
  
  
  Tips &amp;amp; Tricks
&lt;/h3&gt;

&lt;p&gt;Once you &lt;code&gt;npm publish&lt;/code&gt;, you &lt;em&gt;CANNOT&lt;/em&gt; change your package name! Take a moment to solidify your choice of words. Try to keep package names short and descriptive. For an example of what not to do, imagine installing this npm package.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I pity the fool!&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&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; &lt;span class="nt"&gt;--save&lt;/span&gt; @teambit/staged-components.component-status-resolver
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Sometimes, even with an unscoped public package, npm refuses to publish unless you include a flag. Add &lt;code&gt;--access public&lt;/code&gt; to your command and try again.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    npm publish my-package &lt;span class="nt"&gt;--access&lt;/span&gt; public
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;If you enabled 2FA when creating your npm account, you will have to provide the one-time token in your publish command.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    npm publish my-package &lt;span class="nt"&gt;--otp&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;811486
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;I hope you enjoyed this article. Feel free to add suggestions or ask questions in the comments below, and I will get back to you. Thank you for reading, and happy coding!&lt;/p&gt;

&lt;p&gt;Don't forget to 💖 this article and leave a 💭. If you're feeling extra generous, please click my name below to 🎆subscribe🎇!&lt;/p&gt;

&lt;p&gt;-- killshot13&lt;/p&gt;




&lt;div class="ltag__user ltag__user__id__497515"&gt;
    &lt;a href="/killshot13" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&gt;
        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F497515%2F9113bec9-139f-4100-8f2f-1affcd01fd28.jpg" alt="killshot13 image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/killshot13"&gt;Michael R.&lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/killshot13"&gt;Full-Stack Web Developer— Websites · Web Applications · WordPress · SEO · MongoDB · UGA/GA4 Certified · Windows Insider · WP Core · Ethical Hacker · USAF Veteran&lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;






</description>
      <category>npm</category>
      <category>tutorial</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
