<?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>Forem: Sam Robbins</title>
    <description>The latest articles on Forem by Sam Robbins (@samrobbins85).</description>
    <link>https://forem.com/samrobbins85</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%2F314986%2F31a9f9e1-7370-46c8-9f84-5ec09d686ed5.jpg</url>
      <title>Forem: Sam Robbins</title>
      <link>https://forem.com/samrobbins85</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/samrobbins85"/>
    <language>en</language>
    <item>
      <title>Adding captions to images in MDX</title>
      <dc:creator>Sam Robbins</dc:creator>
      <pubDate>Sun, 19 Sep 2021 18:41:53 +0000</pubDate>
      <link>https://forem.com/samrobbins85/adding-captions-to-images-in-mdx-4h4d</link>
      <guid>https://forem.com/samrobbins85/adding-captions-to-images-in-mdx-4h4d</guid>
      <description>&lt;p&gt;Using &lt;a href="https://mdxjs.com/"&gt;MDX&lt;/a&gt; you can overwrite the default components that are provided by Markdown. In this blog I will use this to add captions to images.&lt;/p&gt;

&lt;p&gt;The first thing to do is to look at the &lt;a href="https://mdxjs.com/table-of-components"&gt;table of components&lt;/a&gt; for MDX, and here we can see that images are represented by &lt;code&gt;img&lt;/code&gt;. By following the link we can see the markdown&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="p"&gt;![&lt;/span&gt;&lt;span class="nv"&gt;alpha&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;https://example.com/favicon.ico&lt;/span&gt; &lt;span class="nn"&gt;"bravo"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yields the following items&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;image&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://example.com/favicon.ico&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bravo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;alpha&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;To adapt this component, we are going to use &lt;code&gt;title&lt;/code&gt; as the caption&lt;/p&gt;

&lt;p&gt;Then we create a React component, where each of the keys are passed inside props&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;MyImg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&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;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;figure&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;img&lt;/span&gt; &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;alt&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;figcaption&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;figcaption&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;figure&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;img&lt;/span&gt; &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;alt&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A conditional statement is used here so that no excess formatting is introduced if no title is present. The standard figure layout is used as a tag is there specifically for captions&lt;/p&gt;

&lt;p&gt;You can then pass this component to MDX in the method detailed &lt;a href="https://mdxjs.com/getting-started/#working-with-components"&gt;here&lt;/a&gt; and the captions should not display themselves. You can then apply CSS or classes to the HTML tags in order to style it as you want.&lt;/p&gt;

</description>
      <category>mdx</category>
      <category>react</category>
      <category>caption</category>
    </item>
    <item>
      <title>Prevent a Vercel site from being indexed in search engines</title>
      <dc:creator>Sam Robbins</dc:creator>
      <pubDate>Sun, 19 Sep 2021 18:39:25 +0000</pubDate>
      <link>https://forem.com/samrobbins85/prevent-a-vercel-site-from-being-indexed-in-search-engines-3b65</link>
      <guid>https://forem.com/samrobbins85/prevent-a-vercel-site-from-being-indexed-in-search-engines-3b65</guid>
      <description>&lt;p&gt;There are cases in which you won't want a site to be indexed. For me, this was because I have a previous version of my portfolio website available as a template, and that outdated template was coming up when searching about me because I included some information about me.&lt;/p&gt;

&lt;p&gt;To solve this problem, the &lt;a href="https://developers.google.com/search/docs/advanced/robots/robots_meta_tag"&gt;x-robots-tag&lt;/a&gt; is provided, which allows you to specify if you want your site to be visible on search engines. This tag is to be set as an HTTP header from requests made to the website, and this is made easy in Vercel, you can read more about all the headers &lt;a href="https://vercel.com/docs/edge-network/headers"&gt;here&lt;/a&gt;, and how to implement them &lt;a href="https://vercel.com/docs/edge-network/headers"&gt;here&lt;/a&gt;. In my case, I want the whole site to not be indexed, and so I want a source pattern that covers the whole site, for Vercel this pattern is &lt;code&gt;/(.*)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;There are a range of options for the &lt;code&gt;x-robots-tag&lt;/code&gt;, I'm going to choose &lt;code&gt;noindex&lt;/code&gt;, which will ensure that any of the pages on the site won't be indexed, however links from the site to other sites will be indexed. This is fine for me as it means that social links will be indexed and things like that, however if you don't want any indexing to happen, you can use &lt;code&gt;none&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now to the actual implementation, you want to create a &lt;code&gt;vercel.json&lt;/code&gt; file if you don't have one already, and add&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"headers"&lt;/span&gt;&lt;span class="p"&gt;:[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/(.*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"headers"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"key"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"x-robots-tag"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"noindex"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you already have a &lt;code&gt;vercel.json&lt;/code&gt; file, ignore the outer braces, and just add the &lt;code&gt;headers&lt;/code&gt; key inside your object.&lt;/p&gt;

&lt;p&gt;Your site should redeploy on changing this file, and once it has deployed, then you can run&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-I&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;url]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replacing &lt;code&gt;[url]&lt;/code&gt; with whatever the domain you don't want indexing is. This will give you a big list of properties, the one you're looking for is &lt;code&gt;x-robots-tag&lt;/code&gt;, and it should be whatever you have set it to&lt;/p&gt;

</description>
      <category>google</category>
      <category>vercel</category>
    </item>
    <item>
      <title>My new portfolio website</title>
      <dc:creator>Sam Robbins</dc:creator>
      <pubDate>Wed, 30 Dec 2020 13:11:02 +0000</pubDate>
      <link>https://forem.com/samrobbins85/my-new-portfolio-website-3g2c</link>
      <guid>https://forem.com/samrobbins85/my-new-portfolio-website-3g2c</guid>
      <description>&lt;h2&gt;
  
  
  What I built
&lt;/h2&gt;

&lt;p&gt;I rebuilt my portfolio website using the latest technologies to increase performance and user experience.&lt;/p&gt;

&lt;h3&gt;
  
  
  Category Submission:
&lt;/h3&gt;

&lt;p&gt;Personal Site/Portfolio&lt;/p&gt;

&lt;h3&gt;
  
  
  App Link
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://nextjs-portfolio-pb6dr.ondigitalocean.app/"&gt;https://nextjs-portfolio-pb6dr.ondigitalocean.app/&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Screenshots
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--a6w3_qsv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/18pva6k8zzehk21egw7f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--a6w3_qsv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/18pva6k8zzehk21egw7f.png" alt="Homepage"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--21bebWQj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ituetbuthd4xnwvo4jey.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--21bebWQj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ituetbuthd4xnwvo4jey.png" alt="About Page"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UbXV-4QF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/bfrdmzw0lm7eehuj12q5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UbXV-4QF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/bfrdmzw0lm7eehuj12q5.png" alt="Blog page"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1X6Lcezt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/dvvggb043aled6epbloo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1X6Lcezt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/dvvggb043aled6epbloo.png" alt="Portfolio page"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cqKkdqLL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/z50mk0vweamcl0wnbi31.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cqKkdqLL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/z50mk0vweamcl0wnbi31.png" alt="Writing page"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Description
&lt;/h3&gt;

&lt;p&gt;This site serves as a summary of me online, containing all my skills and experience, along with showing my portfolio projects. In addition, there is also space for a blog and long form writing. &lt;/p&gt;

&lt;h3&gt;
  
  
  Link to Source Code
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/samrobbins85/portfolio-website-v3"&gt;https://github.com/samrobbins85/portfolio-website-v3&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Permissive License
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/samrobbins85/portfolio-website-v3/blob/main/LICENSE"&gt;MIT&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Background
&lt;/h2&gt;

&lt;p&gt;I love working on my portfolio website, and it was working well with Hugo, but there were a lot of features of frameworks like Next.js that I wanted to use. This was a great opportunity to rewrite it, allowing for more development in the future.&lt;/p&gt;

&lt;h3&gt;
  
  
  How I built it
&lt;/h3&gt;

&lt;p&gt;For this I used the digital ocean web service from the app platform. This allows me to run a server, which is used for optimizing the images before sending them to the client.&lt;/p&gt;

&lt;p&gt;This was my first time using Framer Motion, which I used for the animations on the portfolio page. I'm very impressed by its functionality and look forward to learning more about it.&lt;/p&gt;

&lt;p&gt;This was also my first website that I've built with a CMS, choosing GraphCMS as it had all the features I needed. However, during building the website I learned more about what I want from a CMS, so I may change the CMS in the near future.&lt;/p&gt;

&lt;p&gt;Next.js and Tailwind CSS have been part of my tech stack for a while now, and I love using them. Next.js was particularly useful in providing &lt;code&gt;getStaticProps&lt;/code&gt; for fetching all the data from the CMS, and the &lt;code&gt;Image&lt;/code&gt; component, which allows for optimized images, and eliminates layout shift, which will be important in the next year as Google SEO starts to prioritize sites with good core web vitals.&lt;/p&gt;

&lt;p&gt;I expanded my use of Tailwind CSS for this project by building my first Tailwind CSS plugin. This plugin brings the design ideas from &lt;a href="https://latex.now.sh/"&gt;LaTeX.css&lt;/a&gt; to Tailwind. You can see this being used on the writing page of the website. If you want to use the plugin, you can find it on &lt;a href="https://www.npmjs.com/package/latex-tailwind"&gt;npm&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A new package from Tailwind Labs is Headless UI, this makes it easy to produce accessible UIs in a range of frameworks and to style them with Tailwind. This has been used in a small subsection of the portfolio pages where there are multiple GitHub repositories for a single project, so I have a dropdown to list them all. Looking like this:&lt;/p&gt;

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

</description>
      <category>dohackathon</category>
      <category>nextjs</category>
      <category>tailwindcss</category>
    </item>
    <item>
      <title>Next.js vs Gatsby for a portfolio website</title>
      <dc:creator>Sam Robbins</dc:creator>
      <pubDate>Tue, 29 Dec 2020 10:21:24 +0000</pubDate>
      <link>https://forem.com/samrobbins85/next-js-vs-gatsby-for-a-portfolio-website-5g6b</link>
      <guid>https://forem.com/samrobbins85/next-js-vs-gatsby-for-a-portfolio-website-5g6b</guid>
      <description>&lt;p&gt;When choosing a React static site generator, there are two major choices, Gatsby and Next.js, with fairly different approaches.&lt;/p&gt;

&lt;h2&gt;
  
  
  Advantages of Gatsby
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Plugins.&lt;/strong&gt; Gatsby has a huge range of plugins to make things simpler, including connections to CMSs and markdown processing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Image component.&lt;/strong&gt; Both frameworks now have an image component, but Gatsby has had one for much longer and so has had time to make it better.&lt;/p&gt;

&lt;h2&gt;
  
  
  Advantages of Next.js
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;I already know it.&lt;/strong&gt; Obviously this one won't apply to everyone, but there's a big advantage to just choosing the framework you're most familiar with as there's no learning curve.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Increased flexibility.&lt;/strong&gt; Gatsby is very much about "The Gatsby way of building", providing a range of systems in which you can build your app, whereas Next.js is more like an extension of Create React App, making it easier to build a wider variety of applications.  Next.js also provides opportunities for having a backend through &lt;code&gt;getServerSideProps&lt;/code&gt; and their API routes should I ever need to use it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Development experience&lt;/strong&gt;. Gatsby takes a lot longer to start the development server, which makes developing using it a somewhat painful experience on larger or more complex sites. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links with companies to optimize performance.&lt;/strong&gt; As the most popular React framework, Next.js has seen contribution from Google and Facebook, using Next.js as the testing ground for new features.&lt;/p&gt;

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

&lt;p&gt;Overall, I decided to go with Next.js for my new site, and so far I'm very happy with my choice. Both solutions are good however, and you can't really go wrong either way.&lt;/p&gt;

</description>
      <category>dohackathon</category>
      <category>react</category>
      <category>gatsby</category>
      <category>nextjs</category>
    </item>
    <item>
      <title>Moving away from Hugo</title>
      <dc:creator>Sam Robbins</dc:creator>
      <pubDate>Fri, 18 Dec 2020 19:38:17 +0000</pubDate>
      <link>https://forem.com/samrobbins85/moving-away-from-hugo-2ioe</link>
      <guid>https://forem.com/samrobbins85/moving-away-from-hugo-2ioe</guid>
      <description>&lt;p&gt;As part of the &lt;a href="https://dev.to/devteam/announcing-the-digitalocean-app-platform-hackathon-on-dev-2i1k"&gt;Digital Ocean App Platform Hackathon&lt;/a&gt; I am going to remake my Portfolio website. The question here is why, when I have an existing portfolio website that does its job?&lt;/p&gt;

&lt;p&gt;There are many reasons for this, but first I'll go over why I love my current setup&lt;/p&gt;

&lt;h1&gt;
  
  
  Why Hugo is great
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Hugo is really really fast&lt;/strong&gt;, it does in milliseconds what will take other static site generators minutes. This means that I never need to worry about how long my build will take, and so the content is updated as fast as possible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hugo is already set up to be a blogging platform&lt;/strong&gt;, there is built in support to mark files as drafts and so not publish them. You also don't need to add any boilerplate code to get up and running with a blog format where you have a page of all the blogs and lots of blog pages.&lt;/p&gt;

&lt;h1&gt;
  
  
  Why I might want to move from Hugo
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;I can use a CMS&lt;/strong&gt;, this gives a better authoring experience than what is possible with Hugo. I currently use Forestry as a CMS for Hugo, but due to it being git based rather than API based, there is a limit to the features it can provide. An example of this is when adding technologies to my portfolio projects, I have to manually set up the technology each time with title, image and link, whereas with an API based CMS I can predefine the technologies and just include them with one click. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I can use React&lt;/strong&gt;, I'm thinking of moving away to a React based static site generator. This provides an advantage as I don't need to manually include Alpine.js which I currently use for the interactivity and React provides a greater range of features. I can also use React libraries such as Framer Motion to provide animation on the website.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Greater flexibility&lt;/strong&gt;, Hugo is great at doing what it is designed to do, but I was already somewhat stretching the use case for Hugo with single pages beyond the index page. In comparison, React based static site generators are just frameworks for single page apps, and I can make whatever I want with them.&lt;/p&gt;

</description>
      <category>dohackathon</category>
      <category>hugo</category>
      <category>react</category>
    </item>
    <item>
      <title>Making an NPM package for a React component library with Tailwind CSS</title>
      <dc:creator>Sam Robbins</dc:creator>
      <pubDate>Sun, 06 Dec 2020 13:07:56 +0000</pubDate>
      <link>https://forem.com/samrobbins85/making-an-npm-package-for-a-react-component-library-with-tailwind-css-a0h</link>
      <guid>https://forem.com/samrobbins85/making-an-npm-package-for-a-react-component-library-with-tailwind-css-a0h</guid>
      <description>&lt;p&gt;First you need to make an npm package, this can be done with &lt;code&gt;npm init&lt;/code&gt; provided you have npm installed on your computer. For the name if you want a scoped package, e.g. &lt;code&gt;@samrobbins/package&lt;/code&gt;, ensure that the package name follows that structure, otherwise, you can just go with &lt;code&gt;package&lt;/code&gt;. Remember that these have to be unique, so check npm to ensure you're not overlapping. Also ensure that your &lt;code&gt;main&lt;/code&gt; key is &lt;code&gt;output.js&lt;/code&gt;, or if you want it to be something different, then substitute your different name when I use &lt;code&gt;output.js&lt;/code&gt; further down in this file&lt;/p&gt;

&lt;p&gt;The first thing we need is a JavaScript bundler, for this I've chosen rollup, but you could do this with any of them. To install rollup, run&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i rollup
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The config file for rollup is &lt;code&gt;rollup.config.js&lt;/code&gt;, so create that file, and we'll start simple with this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./index.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./output.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;esm&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;This takes the file &lt;code&gt;index.js&lt;/code&gt; and creates a file &lt;code&gt;output.js&lt;/code&gt;, with the format of ES Modules (&lt;code&gt;esm&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;At the time of writing, the postcss plugin we'll use later is only compatible with postcss 7, so we'll install everything for the compatibility version of Tailwind CSS&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;tailwindcss@npm:@tailwindcss/postcss7-compat postcss@^7 autoprefixer@^9
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and create a simple &lt;code&gt;postcss.config.js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;tailwindcss&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt;
    &lt;span class="na"&gt;autoprefixer&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;Then we can initialise Tailwind CSS&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx tailwindcss init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will create a &lt;code&gt;tailwind.config.js&lt;/code&gt; file, and we can add to purge whichever folder we're going to put our components in by adding a &lt;code&gt;purge&lt;/code&gt; key like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;purge&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./components/**/*.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;//...&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a &lt;code&gt;styles&lt;/code&gt; folder with &lt;code&gt;tailwind.css&lt;/code&gt; inside, with the following text&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@tailwind&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;@tailwind&lt;/span&gt; &lt;span class="n"&gt;components&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;@tailwind&lt;/span&gt; &lt;span class="n"&gt;utilities&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows you to use things like &lt;code&gt;@layers&lt;/code&gt; in the future if you need to.&lt;/p&gt;

&lt;p&gt;Now Tailwind is set up, we want to go back to rollup so it understands what to do with it&lt;/p&gt;

&lt;p&gt;For this we want to use the &lt;code&gt;rollup-plugin-postcss&lt;/code&gt; plugin, which can be installed like this&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;rollup-plugin-postcss
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can then use this in your &lt;code&gt;rollup.config.js&lt;/code&gt; file by adding this at the top&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;postcss&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rollup-plugin-postcss&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;Then going into the main object, add a key called &lt;code&gt;plugins&lt;/code&gt;, which is a list of functions, and you can add postcss like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nx"&gt;postcss&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./postcss.config.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;extensions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.css&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="na"&gt;minimize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;insertAt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;top&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we're giving it the path of our postcss path under &lt;code&gt;config&lt;/code&gt;, telling it which files to run postcss on with &lt;code&gt;extensions&lt;/code&gt; and minimizing the output with &lt;code&gt;minimise&lt;/code&gt;. An important key here is &lt;code&gt;inject&lt;/code&gt;, this determines where in the head of your page the CSS will be inserted. This is very important with Tailwind CSS as it has an order of priority, allowing for patterns like &lt;code&gt;block md:flex&lt;/code&gt; and it will use display block less than the &lt;code&gt;md&lt;/code&gt; viewport width, then &lt;code&gt;flex&lt;/code&gt; after that. However, if there is a definition for &lt;code&gt;block&lt;/code&gt; after the definition for &lt;code&gt;md:flex&lt;/code&gt;, then this pattern will not work as expected. So in order for the CSS to work as you would expect, you want it at the top, and the &lt;code&gt;inject&lt;/code&gt; key used as shown does this.&lt;/p&gt;

&lt;p&gt;As these are React components, we expect React to be included in the application we're using these, so we want to add &lt;code&gt;react&lt;/code&gt; and &lt;code&gt;react-dom&lt;/code&gt; as peer dependencies. So add a &lt;code&gt;peerDependencies&lt;/code&gt; key in your &lt;code&gt;package.json&lt;/code&gt; and add the latest versions of those packages, at the time of writing, looking like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"peerDependencies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"react"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^17.0.1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"react-dom"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^17.0.1"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can then specify the same kind of thing in &lt;code&gt;rollup.config.js&lt;/code&gt; by adding these under the &lt;code&gt;external&lt;/code&gt; key like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;external:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"react"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"react-dom"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next we want to generate the &lt;code&gt;index.js&lt;/code&gt; file we referenced earlier. How specifically you export from your component files may change this, but for my example, I'm doing &lt;code&gt;export default&lt;/code&gt; from all my component files. So for each component I have, I want to add a line that looks like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;Answer&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./components/answer.js&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;This will reexport the default export as &lt;code&gt;Answer&lt;/code&gt; from this file. &lt;/p&gt;

&lt;p&gt;If you run &lt;code&gt;rollup -c&lt;/code&gt; (&lt;code&gt;-c&lt;/code&gt; specifying that you have a custom config) you should see that it builds to an &lt;code&gt;output.js&lt;/code&gt; file. However if you look in here, you will see that the CSS is huge as Tailwind doesn't know if you're running locally or in production, and so assumes local and includes all the styles. You can quickly get around this by running&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;NODE_ENV&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;production rollup &lt;span class="nt"&gt;-c&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;but any way to set the environment variable &lt;code&gt;NODE_ENV&lt;/code&gt; to production will work&lt;/p&gt;

&lt;p&gt;We also want to add babel to this project, which allows for using newer JavaScript features on older browsers.&lt;/p&gt;

&lt;p&gt;To do this, we need to install a few packages to get all the features we need&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; @babel/core @babel/preset-env @babel-preset-react @rollup/plugin-babel babel-loader
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In our &lt;code&gt;rollup.config.js&lt;/code&gt; we need to import the rollup plugin we just installed by adding this at the top&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;babel&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@rollup/plugin-babel&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;and then this new entry in our &lt;code&gt;plugins&lt;/code&gt; array:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;babel&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;babelHelpers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bundled&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;exclude&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;node_modules/**&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and finally to tell babel what we want it to do, create a &lt;code&gt;.babelrc&lt;/code&gt; file in your root directory with the following code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"presets"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"@babel/preset-env"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@babel/preset-react"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  NPM publishing
&lt;/h1&gt;

&lt;p&gt;Now we want to publish this package to npm, so make sure you have an npm account, then login with &lt;code&gt;npm login&lt;/code&gt;, and add the flag &lt;code&gt;--scope&lt;/code&gt; with your username, so I do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm login &lt;span class="nt"&gt;--scope&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;@samrobbins
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then to publish from the command line you can do&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 &lt;span class="nt"&gt;--access&lt;/span&gt; public
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and this will publish it to npm. You need the &lt;code&gt;--access public&lt;/code&gt; flag if you have a free account as scoped packages default to restricted but restricted packages are paid on npm.&lt;/p&gt;

&lt;h1&gt;
  
  
  GitHub action
&lt;/h1&gt;

&lt;p&gt;Now we have a published package, but it's a bit of a pain to have to do this manually every time, so you can go further by creating a GitHub action to do it automatically&lt;/p&gt;

&lt;p&gt;You can do this by creating a file insider &lt;code&gt;.github/workflows&lt;/code&gt; of the &lt;code&gt;yml&lt;/code&gt; format, for example, I created &lt;code&gt;publish.yml&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We'll go through this step by step, but if you want the whole file I'll put it at the bottom&lt;/p&gt;

&lt;p&gt;First we want a name for our workflow, so we can see from the UI what is running if we have multiple actions, so set&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;or whatever you want it called.&lt;/p&gt;

&lt;p&gt;Next we want a trigger for this, I've chosen to have it when I create a GitHub release so that GitHub releases and NPM are in sync, but you can change the trigger if you want.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;release&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;created&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we want to determine what is actually running. We don't need any operating specific features, so &lt;code&gt;ubuntu&lt;/code&gt; is the best choice for the operating system to run it on.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The rest of these steps sit underneath the &lt;code&gt;build:&lt;/code&gt; key just like &lt;code&gt;runs-on&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;First we want to get the code from our repository, this can be done with the &lt;code&gt;actions/checkout&lt;/code&gt; action&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we want to set up our Node.js environment. Using the latest version of Node.js is suggested as some packages will use more modern Node.js features, for example I had Tailwind fail on Node.js 10. And we want to use the official npm registry as that's the one everyone is used to, but if you want to use something like the GitHub package repository, you could change that here.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- uses: actions/setup-node@v1
    with:
        node-version: '12.x'
        registry-url: 'https://registry.npmjs.org'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we want to install all our packages, and run the build command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm install&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm run-script build&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And finally we want to publish. Instead of using &lt;code&gt;npm login&lt;/code&gt; like we did locally, here we want to instead use a token. This can be found on the npm website, and make sure you get a &lt;strong&gt;publish&lt;/strong&gt; token. Then add this as &lt;code&gt;NPM_TOKEN&lt;/code&gt; in the repository you will be running the action in.&lt;/p&gt;

&lt;p&gt;This will allow the final statement to work&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm publish --access public&lt;/span&gt;
      &lt;span class="s"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;NODE_AUTH_TOKEN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.NPM_TOKEN }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So in total, the file should look like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Node.js Package&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;release&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;created&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@v1&lt;/span&gt;
      &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;12.x'&lt;/span&gt;
        &lt;span class="na"&gt;registry-url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;https://registry.npmjs.org'&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm install&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm run-script build&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm publish --access public&lt;/span&gt;
      &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;NODE_AUTH_TOKEN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.NPM_TOKEN }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's it! Whenever you create a release, it'll be published&lt;/p&gt;

</description>
      <category>tailwindcss</category>
      <category>react</category>
      <category>npm</category>
    </item>
  </channel>
</rss>
