<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Jake Varness Blog]]></title><description><![CDATA[Welcome to my blog, where I routinely post about topics related to software development, coding, career development, and more!]]></description><link>https://jvarness.blog</link><generator>GatsbyJS</generator><lastBuildDate>Mon, 23 Feb 2026 20:23:32 GMT</lastBuildDate><item><title><![CDATA[I Used ChatGPT to Edit a Pokemon Save File]]></title><description><![CDATA[Pokemon is one of my favorite video game series ever. Aside from Generation 4, I’ve worked
my way through each of the different regions in…]]></description><link>https://jvarness.blog/nerdery/pokemon-gold-chatgpt-egglocke-1/</link><guid isPermaLink="false">https://jvarness.blog/nerdery/pokemon-gold-chatgpt-egglocke-1/</guid><pubDate>Wed, 18 Feb 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Pokemon is one of my favorite video game series ever. Aside from Generation 4, I’ve worked
my way through each of the different regions in the mainline Pokemon games. Avid Pokemon fans
might resent me for this… But I’ve never actually finished a playthrough of Platinum or HG/SS.
Can I still call myself a true fan if I haven’t done that? I’ll let you be the judge.&lt;/p&gt;
&lt;p&gt;For today, I wanted to post about something I’ve been experimenting with recently. Streamers who
play Pokemon games find many fun ways to play this 30-year-old game series, many of whom adapt
the Nuzlocke format in order to make runs more challenging and/or interesting. One format that I
always thought was interesting was the Egglocke: a format where a save file is customized with a
collection of eggs, many generated by followers or friends of the streamer. The spirit of a Nuzlocke
still exists in this format: you catch a Pokemon in every new route you visit, but instead of keeping
that Pokemon, you grab an egg from your boxes and you release what you caught. That’s what makes
it an “Egg”locke.&lt;/p&gt;
&lt;p&gt;I’ve always liked the idea of this type of run before! Every Pokemon game limits your collection
to the species of Pokemon that you have access to as the game progresses. In Generation 2, there
are also some Pokemon that were brand new to the series that you could &lt;em&gt;only capture in the postgame content&lt;/em&gt;.
No Houndour, Larvitar, or Murkrow without beating the Elite Four first. What if you had a chance to
use one of these Pokemon earlier in the game though?&lt;/p&gt;
&lt;p&gt;For a while, I sort of gave up on the idea of doing an Egglocke in any of the games. Not because
I didn’t think it would be fun or interesting, but because… Well… The setup would be arduous:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I’d have to have two copies of the game, two consoles, and a link cable. Not exactly cheap.&lt;/li&gt;
&lt;li&gt;I’d have to get far enough in one of the games to gain access to most of the Pokemon I would want to use.&lt;/li&gt;
&lt;li&gt;In that same game, I’d have to then &lt;em&gt;breed&lt;/em&gt; all the Pokemon eggs, which is not a fast process.&lt;/li&gt;
&lt;li&gt;I’d have to get far enough in the &lt;em&gt;other&lt;/em&gt; game to catch enough throwaway Pokemon to trade the eggs over.&lt;/li&gt;
&lt;li&gt;I’d have to then link together both games, trade 5 eggs over at a time, until all the eggs I bred were transferred.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;😀&lt;/p&gt;
&lt;p&gt;Then I’d be able to start playing the game!&lt;/p&gt;
&lt;p&gt;🥲&lt;/p&gt;
&lt;p&gt;By the time I’d be done with all that, I would have a couple dozen hours into one game, a couple more hours
into another, with one of the games basically completed. Gold and Silver are basically the same game, and
while Crystal does have some major content differences, it’s mechanically the same game with the same
characters and everything. It would be a pretty big waste of time to have to do all that setup in one
game just to play a different game in a similar way.&lt;/p&gt;
&lt;p&gt;Plus: there’s no randomness involved! If I’m the one breeding all the Pokemon, I already know what each
egg &lt;em&gt;could&lt;/em&gt; contain instead of it being a surprise. That’s one of the big things that makes a Nuzlocke
fun: you can’t predict which Pokemon you’re going to encounter, and you have to make due with what you
get. I could try modifying a save file from my Analogue Pocket using PkHex, but I’ve got two major
problems standing in my way with that: 1. I don’t have a Windows PC anymore after they prevented many
Windows 10 laptops from upgrading, and 2. there’s still not element of surprise if I’m choosing the
eggs that get added.&lt;/p&gt;
&lt;p&gt;For a while, I gave up on the whole idea.&lt;/p&gt;
&lt;p&gt;But then I got a ChatGPT subscription 😎&lt;/p&gt;
&lt;p&gt;You know what you can use in ChatGPT with a subscription?&lt;/p&gt;
&lt;h2&gt;Agent Mode&lt;/h2&gt;
&lt;p&gt;I used ChatGPT Agent Mode briefly a couple of times before this, but before I get into how I used it,
let me explain the difference between Agent Mode and some of the other modes you may be familiar with.&lt;/p&gt;
&lt;p&gt;ChatGPT has several modes you can use for various tasks. It’s got a Web Search mode that will literally
Google that for you: it’s pretty useful if you want to ask ChatGPT something but you want it
to use context from the internet to provide a more accurate and informed answer. Deep Research allows
you to present ChatGPT with a research topic that you want it to investigate and give you a detailed
report on. In the past, I’ve used Deep Research mode to do market research on potential app ideas.
It’s saved me a lot of time not developing something that already exists or isn’t viable. Deep Research
is a lot like Web Search, except it’ll go much more in-depth and work for significantly longer than
it will in Web Search mode. Create Image mode is capable of either creating an image from thin air,
or it can also edit existing images based on a prompt.&lt;/p&gt;
&lt;p&gt;It’s also got a couple other modes I haven’t used as much like Study and Learn mode and Shopping mode,
but the real star of the show here is Agent Mode.&lt;/p&gt;
&lt;p&gt;See, in the other modes I’ve mentioned, ChatGPT relies mainly on web searches to provide you with
results and information. You ask it something in a textual form, it gives you textual responses,
summarizes information, etc. It doesn’t really &lt;em&gt;do&lt;/em&gt; much apart from giving you walls of text
to read.&lt;/p&gt;
&lt;p&gt;Agent Mode is &lt;em&gt;very very different&lt;/em&gt;. In Agent Mode you can give ChatGPT various files and other kinds
of context, and it will perform work within a virtual Linux environment to complete various tasks.
It will perform web searches as it needs to, it’ll use Python scripts or other Linux utilities to
modify files, it’s fun watching it work! The only other time besides the current subject I’ve actually
used Agent Mode was when I was asking ChatGPT to create a holiday-themed letter, and it… Did ok for
the most part 😅&lt;/p&gt;
&lt;p&gt;In using Agent Mode, it hit me: what if I asked ChatGPT to help me create a save file for an Egglocke?
Well I asked it if it could! But… It couldn’t.&lt;/p&gt;
&lt;h2&gt;Guardrails&lt;/h2&gt;
&lt;p&gt;I started out just asking ChatGPT if it could just… Generate a save file for me. Not the ROM, just
a save file.&lt;/p&gt;
&lt;p&gt;Turns out, there’s several reasons why ChatGPT can’t do that, many mostly being legal, but also
from a technical perspective. Save files for Pokemon games are very complex, the data for each Pokemon
is very unique to the game, the player’s progress, and data generated at the start of the game. From a
technical feasibility standpoint, it would be very difficult to just create a file that could be dropped
into a game.&lt;/p&gt;
&lt;p&gt;From a legal standpoint, creating a save file from thin air would be considered creating a derivative
work of Pokemon, which would land you in hot water with Nintendo. ChatGPT specifically has guardrails
in place that would prevent any of it’s models from generating any kind of content that would violate
copyright or other intellectual property laws.&lt;/p&gt;
&lt;p&gt;So I couldn’t have it create a save file for me… But… What if I… &lt;em&gt;Gave it one&lt;/em&gt; to use?&lt;/p&gt;
&lt;h2&gt;Attempt 0&lt;/h2&gt;
&lt;p&gt;Using my Analogue Pocket, I was able to grab the save file for Pokemon Gold, and then I was able to
send it off to ChatGPT’s Agent Mode! This was the first prompt I tried:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;This file I&apos;ve attached here is a Pokemon Gold save file.

I want you to create a save file that will allow me to do what is called an Egglocke: I want you to generate 30 eggs at random that I can hatch after I catch a pokemon on a route in Pokemon Gold. Here are the conditions for the generation:

- Only generate first-stage pokemon in the eggs: no evolved forms of any pokemon. For example, Charizard should not be allowed, but Charmander could be; Kingdra is not allowed, but Horsea could be, etc.
- Do not put legendary pokemon in the eggs, so no Mewtwos or Mews or anything of that sort
- Make one of the eggs contain a shiny pokemon. Do not generate more than 1 shiny.
- Put all pokemon eggs you generate this way into boxes 2 and 3&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In Agent Mode, it browsed the web and used various CLIs and Python scripts in order to edit the file,
and once it finished up I was able to load that save file into my Pocket, and I was actually really
surprised with the results!&lt;/p&gt;
&lt;p&gt;I really wish I had actually saved what it had generated and taken a few screenshots, but I wasn’t
thinking about making a blog post about this at the time… Sad day for me. In this save file, I was in
Cherrygrove City, the second city in Johto the player encounters. When I went to the Pokemon Center and
opened my boxes, I was plesently surprised to see that ChatGPT did in fact generate 30 eggs! I was
elated!&lt;/p&gt;
&lt;p&gt;… Until I hatched one of the pokemon. It was a Geodude.&lt;/p&gt;
&lt;p&gt;“Oh but Jake”, you’re thinking, “Geodude isn’t that bad, you’re overreacting, go to Violet City and
defeat Falkner!“. And normally you’d be right. But it being a Geodude wasn’t the issue. The issue
was that it was a level 1 Geodude. A level 1 Geodude that didn’t have any moves. It didn’t know
Tackle or Defense Curl. I didn’t even bother checking to see which Pokemon in my boxes was shiny
at that point, I just knew that there wasn’t any way I was going to be able to continue on this
file if I was only going to be hatching Pokemon that didn’t know any moves.&lt;/p&gt;
&lt;p&gt;So I gave it the same save file, but told it:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;I want you to do the same thing to this file, except:

- The pokemon you generate can&apos;t have no moves: that&apos;s going to corrupt the save file. The pokemon when they hatch should hatch with the moves they normally would if they were to hatch under normal conditions in the game.
- Make the EVs/IVs random: don&apos;t make all of them completely 0. Obviously for the shiny you&apos;re constrained, but for all the other ones don&apos;t make them all 0.
- This is a fresh save file. I want you to fill up the first two boxes with eggs now, not just 30.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Attempt 1&lt;/h2&gt;
&lt;p&gt;I went back to Cherrygrove City and opened my boxes and I hatched my first Pokemon: a Sandshrew!
But this time, it actually knew some moves! But… It was also still at level 1. I was able to
switch-train it up to level 5 and start my journey!&lt;/p&gt;
&lt;p&gt;I made it to Azalea Town where the second gym badge is. All the other eggs I hatched up until
that point pretty much met my expectations: they were all first-stage Pokemon, no legendaries,
but they were all still at level 1.&lt;/p&gt;
&lt;p&gt;But then, I hatched a couple other Pokemon and something… Weird had happened. I got a Vulpix
and a Nidoran. These two, unlike the previous eggs, hatched at Level 5. I thought that was a
little strange at first, but I didn’t realize how strange it was going to get:&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 160px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/721fde51dbfe28fedfdaee7effe6e65d/69538/lvl-5-vulpix-0-exp.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 89.86486486486487%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAASCAIAAADUsmlHAAAACXBIWXMAAAsTAAALEwEAmpwYAAADeElEQVR42l1QW28aZxDdX9J/UCW/oZX60Ke+N5GqRm4Vt6oVJ8RpnDi1ZasttdvGDhjMnbgPQEggWCAwIWBiYizWIGNTg3G8XLxa7rALe2V3Mwu5qB2NdmfmO2fOzCDy2CQJfAj/UcYwjMfjqdfrkUjE7XaHw2FRFJPJpMvlGr/G43EIkHdMWa4epRMbv10U8xAPh0OCIHq9Hk3T0IIkSY7jKIqCrzQyAChkIFIk2ex0jZNf/33pk7D2T6iyDANq2Ww2lUp5vd5YLIai6P7+/pjzwZBSFt39Y3prfubJ0m33lU9Ptp2jWUTA8Tw/FgfBZqPZp/ocz/2HfPZs1f3l5ZXPLjPWa9sLk6fHh+NFYEkcx4+Pj8eyr5Kv0tk0ih4IgvCRnNCo7Fe/evLtF9arn5sX7pdyOaiKIwMciLMcC/tjLzFsp9QiCYanaE7os8yg30cqB5FaIWtd/svrcDVrxEhV+tBbEpX4ue95WBUqaqoPY9/4s4uu9KlxJ5KIRhG83MQxovqm2m30cAwvF0qVYqVarFbOKtgphp/jF+cXUCkeFku58mn+3zeF/Fm+dJbHqsUK0tTUGtr6wDzom/rwBactNGtjsRUsejdK6amWtkWsEbSJrmlqPR0J3tF12tpWe72NaH+YWbxyw67edKw6nKtO15rrqeapbkln/86+N7sXvBmMzkR37+6yG+zOnR2opOZSsZkYOoe+UL1AOCNDrncDqoBpwnSiPunqu36V3/q9tbRcSt5LynZZMAqSTZKtsmSVIFZSi8Qa2NCtEDLQ09B1oB90NV3GwEDMbDCiSWw/aidmE0Cm1il4pbQUFGWLDJietieZlUZIYDpwtHiEPkBzS7nEvURwOlheKYtmEXrBePDkm/KlHqSck87CrwUgR+9EQzdDwAQZBBoPjcP6wzoI8kae0TPxn+OZ+UznUQdWBTRv4HkzD2ioCAYBZJ3Xnf4bfsd1B3LwywH41tTW44nH5+pzmAd6Aae91lLG/kcWTUrK6pnswmFmPs0buJe3I5sTm7Sehp0HMF5mIeP+0e35yQM44Ms2ILdfz76GVDALcC1w0SYNLUrAm4e0gYWbIQAVrSIMDDdUTmKWFbfJjdUGSAVvbVtmU4Flwvd7xaeubKmrEARX6va5tHfKhwBUkbLI72jvyaC8N1LuaClSR//Pe+t9doN9C5RDa4z/JQAtAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;A screenshot of the stats screen of Vulpix at Level 5 in Pokemon Gold&quot;
        title=&quot;&quot;
        src=&quot;/static/721fde51dbfe28fedfdaee7effe6e65d/69538/lvl-5-vulpix-0-exp.png&quot;
        srcset=&quot;/static/721fde51dbfe28fedfdaee7effe6e65d/12f09/lvl-5-vulpix-0-exp.png 148w,
/static/721fde51dbfe28fedfdaee7effe6e65d/69538/lvl-5-vulpix-0-exp.png 160w&quot;
        sizes=&quot;(max-width: 160px) 100vw, 160px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;See how Vulpix has 0 EXP? Even though it’s level 5? Turns out that’s not good. Pokemon pretty much
always hatch with exactly the amount of EXP they would to have at the level they hatched at. However,
Vulpix was at level 5 here with 0 EXP. What ended up happening here is that when Vulpix gained any
amount of EXP, it leveled “up” to level 2. How? By leveling all the way up to level 100 first, then
resetting back to 1, then 2. I ended up with a level 2 Vulpix that had a cracked moveset for the
second badge:&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 160px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/6f37a1aca591d9790a28b5edd22e433f/69538/stacked-vulpix.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 89.86486486486487%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAASCAIAAADUsmlHAAAACXBIWXMAAAsTAAALEwEAmpwYAAADU0lEQVR42nWRe1MSYRTG95P0DZr6DDXTzcpb3lKappqpuF9ctYuVGd1typlsJg0NEAR2URuzBhkSMUsHqIkWUS5FEZFJ6sKyuyyXDmxj/ZHvPANnz57n/Z1zFinyp1AA5eC//ETT9NjY2MrKisPhwHHcbrfn8/mFhQWtVgsBvHW5XFCG/HEWi7GP7+Ye3/wWWoI4l8slEomNjY1MJgNXkCSZzWbhkaKocnkBCkpmMKZIcnVtfUDYfH/HNnvfPcgyNA00n8/ndrvHx8edTqfH4wEy79k8SNTneX1HOdHVjqnb8JbtgSlzuZc81PE0gLMsm0wmAcswdL7w14+ER3vxAzt7du2kh05OXRUGiQ/8IDBbPB4nCAKwwHfOOD1er+/9Isf9Y557iGoFVdiJPUOC3ZqrnVG/H7L58uE4DuAMzawmV1kqm1pPOUL981FzimIplkmn00jc6/y57Nf19E6YR5OJFX4fm3fzsW3GNql+4dW/6wtVDHrq+1/NP52dnXs1jQSjkUBoyR/wxxKxz/Fw+MvS53iIV+TrMuhTLBiMLi4GfMtBPxFx+8NeIkIQkY/haABRTzfdfiNATVVXbA0GUmHKqAa+nO2PntXERSOU0kyrLEwrxrZiHIplUSvXgbPtGIviWdSSRRE9KTZzCiMlM1ASa1EFsnByEyMbWhXiORXGKSFvzEhNrNyQlgynxJacwkTLIWmgpMgVe92t+eZbC83nn1XjRRVotIjC62szDQ+I4z1ewSXbEal2/x1PS7ezoc1aqZ5t6hivkg9XwC8C11s4JZZVYnklby6pUErq1yX6DYnmh1Ck2aswVOhJSbezUTy4ry908vLUkfbRSgQvt2otqDad1mIrDHLXe+y2u6XLUad2NXa+rJXpDnS+qNWtiwHePd3Q6z8+nJIif2n/CLp4mhQZMlLtmhgEbUt1+zU/zkDncNGjyKkbc0e7HPX/MQN5hJapZxvvegTnnlWfn6ge/ClEscOXbXXd0/UXJ2tNrAKwujXJlmRDWmqkZbDtJ9/PKI0H2/BKjFFdczXCqP2x09dfN3WMVW1BZuQXntfcfHuUH1j7SwQo2CJ8nuG0FDZSCsgtyCXlVVAEOx+h5KLBva3mQ8aMTDK0j58ZgouTNb8BCe0Ubbo8ZkcAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;A screenshot of Vulpix at Level 2 in Pokemon Gold that knows Flamethrower and Confuse Ray&quot;
        title=&quot;&quot;
        src=&quot;/static/6f37a1aca591d9790a28b5edd22e433f/69538/stacked-vulpix.png&quot;
        srcset=&quot;/static/6f37a1aca591d9790a28b5edd22e433f/12f09/stacked-vulpix.png 148w,
/static/6f37a1aca591d9790a28b5edd22e433f/69538/stacked-vulpix.png 160w&quot;
        sizes=&quot;(max-width: 160px) 100vw, 160px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;I decided that what I’d do from this point on is if I encounter a bug or glitch like this, I’d
make ChatGPT generate a new save and try again.&lt;/p&gt;
&lt;p&gt;This time around though, I did actually pop the file into &lt;a href=&quot;https://pkhex-web.github.io/&quot;&gt;PkHex Web&lt;/a&gt; and
I did examine the boxes and everything. Interestingly enough, it had a couple duplicate pokemon in there,
and it also had no baby Pokemon or Pokemon that didn’t evolve. The Pokemon all appeared to also start at level
1 like the other Pokemon I had hatched.&lt;/p&gt;
&lt;p&gt;And the shiny Pokemon? None other than Geodude. I’m starting to think Geodude may be ChatGPT’s favorite Pokemon.&lt;/p&gt;
&lt;h2&gt;Attempt 2&lt;/h2&gt;
&lt;p&gt;So I decided the night that I was typing this whole post up that I wanted to have ChatGPT try once more to generate
the eggs. This time I fed Agent Mode THIS prompt:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;This file I&apos;ve attached here is a Pokemon Gold save file.

I want you to create a save file that will allow me to do what is called an Egglocke: I want you to generate eggs at random that I can hatch after I catch a pokemon on a route in Pokemon Gold. Here are the conditions for the egg generation:

- Only generate either first-stage pokemon, or pokemon that can&apos;t evolve in the eggs: no evolved forms of any pokemon. For example, Charizard should not be allowed, but Charmander could be; Kingdra is not allowed, but Horsea could be; Pichu is ok, but Pikachu shouldn&apos;t be because it evolves from Pichu; Miltank, Skarmory, and Tauros don&apos;t evolve, so that can be placed in an egg, etc.
- Do not put legendary pokemon in the eggs, so no Mewtwos, Mews, legendary dogs/birds, or anything of that sort
- Make one of the eggs contain a shiny pokemon. Do not generate more than 1 shiny.
- Fill the first two boxes with the pokemon eggs you generate.
- The pokemon you generate can&apos;t have no moves: that&apos;s going to corrupt the save file. When the pokemon hatch, they hatch should hatch with the moves they normally would if they were to hatch under normal conditions in the game.
- Make the EVs/IVs random: don&apos;t make all of them completely 0. Obviously for the shiny you&apos;re constrained, but for all the other ones don&apos;t make them all 0.
- Each pokemon should hatch at level 5. This is Generation 2, so each pokemon needs to hatch with the correct amount of EXP to make it a level 5 pokemon.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Pretty reasonable prompt I’d say, except… I didn’t exactly read the output from ChatGPT. One of the things it
said was:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Experience and levels: Each Pokémon’s EXP was set to a value appropriate for level 5 (100, 125, 135 or 156 depending on growth group) so they hatch at level 5. This matches the experience thresholds for the Gen II growth formulas (e.g., medium fast uses n³ = 125 and slow uses 5n³/4 = 156).&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now this isn’t incorrect for ChatGPT to say: these EXP values are exactly what you’re supposed to have for newly
hatched pokemon starting out at level 5. This isn’t really important until I show you what I got when I hatched the
first egg from this new save file. What I &lt;em&gt;didn’t&lt;/em&gt; read, however, is that ChatGPT thought that it should
infer what &lt;em&gt;moves&lt;/em&gt; a Pokemon was supposed to have when it eventually hatched:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Move sets: Each egg’s move list contains Tackle (ID 33), Growl (45), Quick Attack (98), and Poison Sting (40). These moves are all early‑game moves (Tackle, Growl and Poison Sting appear in the low‑index move list, and Quick Attack is also an early‑level move), and Bulbasaur’s Gold/Silver learnset confirms that Pokémon normally have moves like Tackle and Growl before level 5. Assigning these ensures each egg has valid moves on hatching.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So you could imagine my surprise when I hatched my first egg and it was a Charmander! Charmander is a great
starting pokemon to have! Except… It didn’t know Scratch and Leer like it was supposed to know being level 5.
Instead it knew Tackle, Growl, Quick Attack, and Poison Sting.&lt;/p&gt;
&lt;p&gt;To my surprise, it also had like… 86 Million EXP points… But it was still somehow level 5? I was quite perplexed,
and since I wasn’t going to start using this file for obvious reasons, I decided to take a look at the other Pokemon
ChatGPT had generated for me.&lt;/p&gt;
&lt;p&gt;Every Pokemon in those eggs was Level 100, and knew Tackle, Growl, Quick Attack, and Poison Sting 🙃🙃🙃&lt;/p&gt;
&lt;p&gt;Not exactly what you want when you’re first starting the game! Or trying to finish the game for that matter!&lt;/p&gt;
&lt;p&gt;What I did appreciate though, is ChatGPT did &lt;em&gt;correctly&lt;/em&gt; generate a slightly more random set of Pokemon that
weren’t all just first-stage Pokemon: on examination of the save, there was Shuckle, Pinsir, and a few other
Pokemon that didn’t have evolutions in Generation 2. And there was a Geodude, but this time it wasn’t shiny
and it did have moves. Instead I had a shiny level 100 Growlithe that knew Tackle, Growl, Quick Attack, and
Poison Sting!&lt;/p&gt;
&lt;h2&gt;For Next Time&lt;/h2&gt;
&lt;p&gt;Overall, I’ve really enjoyed using ChatGPT for something fun as opposed to productive. At the time
of writing this, I’m working on a new prompt, and I’m going to start Attempt 3. Hopefully I don’t fail, and
hopefully Agent Mode doesn’t fail me either!&lt;/p&gt;
&lt;p&gt;A couple of closing thoughts that I did have after experimenting:&lt;/p&gt;
&lt;p&gt;Pokemon save files are definitely complex little pieces of binary data: even with some sort of “template”
to go off of, even AI still has issues generating binary data with any amount of integrity. I’ve seen posts
online about coding agents eventually modifying the straight binary files instead of writing code, and
after seeing what Agent Mode does to a save file… I’m not convinced AI is anywhere close to that.&lt;/p&gt;
&lt;p&gt;This does make me wonder though: I’m using ChatGPT Agent Mode to modify the save file. What if I were to
use a CLI agent like Codex instead? Would I be able to have it modify the file in such a way that the data
integrity is sound? Would it actually do better than ChatGPT’s Agent Mode?&lt;/p&gt;
&lt;p&gt;I’ll definitely explore that another time, but until then, I hope you found this to be an entertaining
read, and if you have questions or comments about this little experiment, feel free to reach out to
me on my socials at the bottom of the page!&lt;/p&gt;
&lt;p&gt;Happy hunting, folks.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Reflections on Agentic Coding]]></title><description><![CDATA[2025 went out with a bang in the world of software engineering. Coding agents like
Claude and Codex and Copilot and the recently viral…]]></description><link>https://jvarness.blog/software-engineering-in-2026/</link><guid isPermaLink="false">https://jvarness.blog/software-engineering-in-2026/</guid><pubDate>Sat, 17 Jan 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;2025 went out with a bang in the world of software engineering. Coding agents like
Claude and Codex and Copilot and the recently viral OpenCode have transformed the way
engineers work on a daily basis. Prior to 2024, AI was more of a joke than a tool
people took seriously. I myself remember working as an engineer in 2024 and &lt;em&gt;barely&lt;/em&gt;
using ChatGPT to solve some problems in languages and tools I wasn’t as familiar with,
asking it what problem space I was in and seeing if it could solve tricker problems for
me. I primarily used VS Code to write all my code, and it was still me actually writing
it. No tab complete. No AI agents. Just good ol fashioned ass-in-seat, hands-on-keyboard
coding.&lt;/p&gt;
&lt;p&gt;Towards the beginning of 2025 however, I started to adopt Github Copilot into my
coding tasks. It pretty much all started out as just using tab-complete to write
code and tests. I wasn’t really delegating or handing off tasks to it, more so
allowing the tab-complete to save me some time and effort, while watching it be
kind of correct some of the time, making manual adjustments, and coming up with
something that worked well.&lt;/p&gt;
&lt;p&gt;Throughout 2025, I slowly started adopting agentic coding. First, I started out
using Windsurf’s SWE-1 model within Cascade to generate code changes and files
that I needed. It worked ok, but I found that a lot of the time I needed to go
in and do some pretty significant rework of a lot of the stuff it generated in
order for it to be ready. Granted, I was a lot worse at prompting around this
time too, so it was probably just as much a reflection of my own skill using
agents as it was the agent itself.&lt;/p&gt;
&lt;p&gt;Even with the rework, I was still finding in-editor coding agents to provide
a decent productivity boost: I couldn’t fully trust the work, but I was finding
the models capable of getting me around 70% of the way there, and it was still a
lot faster than me writing it out by hand, telling VS Code to make me new files when
I needed it to, copy-pasting test files and tab-completing them until they passed…
AI was becoming more of a companion than ever.&lt;/p&gt;
&lt;p&gt;Throughout the summer and going into fall, as Claude Code gained more popularity,
I started trying to figure out if it was possible for me to use open-source and
free models locally as an alternative to paying any AI subscriptions. As it turns
out, running LLMs locally is really challenging and resource-intensive. I started
to realize that as nice as my M1 Pro with it’s 16 GB of RAM really is, it was
nowhere near enough hardware to run any good LLM locally.&lt;/p&gt;
&lt;p&gt;October was really where I caved: I needed to understand what all the agentic
coding hype was all about, and that’s when I did some research using ChatGPT and
Claude to figure out which offering was better: Claude Code or Codex. In retrospect,
I made the right decision to use Codex as opposed to Claude. Reddit in recent months
has been blowing up with posts about how bad Claude has been working for them:&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 590px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/d6196309f6bc9c940bce0341781b7647/07a9c/claude-ai-reddit-1.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 21.62162162162162%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAy0lEQVR42n2Pyw7CIBBF+/8r4yfoR5i4N/6AmkhaWwot9EF89U3jdcDo0sXJMGHmHgh0kUNmKaRMwfkFQiSI49D3SklEEUOWCRhTIk1jX/u+QdveiYenaT7ncewQlBTGzydIGnYBLjDPBQUmBEdVaWy3GyyXCxJFFJp4rtfac7uZXx2GFkG13yFZr/AIGaaXxUB2Z3K4gWnqacGgKBS67vm7m+cR1o6+frF2QFBo+hY7wNSKzCHqSkFrQSElGDvSqzleJAJmWui94B9vzaQr9rS0FD8AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Reactions to Claude Code at the start of 2026&quot;
        title=&quot;&quot;
        src=&quot;/static/d6196309f6bc9c940bce0341781b7647/fcda8/claude-ai-reddit-1.png&quot;
        srcset=&quot;/static/d6196309f6bc9c940bce0341781b7647/12f09/claude-ai-reddit-1.png 148w,
/static/d6196309f6bc9c940bce0341781b7647/e4a3f/claude-ai-reddit-1.png 295w,
/static/d6196309f6bc9c940bce0341781b7647/fcda8/claude-ai-reddit-1.png 590w,
/static/d6196309f6bc9c940bce0341781b7647/efc66/claude-ai-reddit-1.png 885w,
/static/d6196309f6bc9c940bce0341781b7647/c83ae/claude-ai-reddit-1.png 1180w,
/static/d6196309f6bc9c940bce0341781b7647/07a9c/claude-ai-reddit-1.png 1440w&quot;
        sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 590px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/620735a45715fb0e275fe5c2a955bb53/52ab5/claude-ai-reddit-2.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 19.594594594594593%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAABYlAAAWJQFJUiTwAAAArklEQVR42o2P2Q6CMBRE+/9f5S+YoLSllTVQoQUFZTdjaSKJL8aHk7vM3JsMEWEAys7wfQ+Unhyc+xCCuco5RRAwRJF02rZPkhBSBhZuNYqiyLAsI+Z5AKlkDBXGaO4GRl9R15VFw5jS1bJUrt/M4/h0TFO/s82b9oGowxE3GmF+TRj6bjcNwwNdd3OmdZ2+jn5Bcp0hLSJUVW6jCGhdQKkUaXoBYx7atrFx/n/4Bmh9Lhloxow3AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;More Reactions to Claude code in 2026&quot;
        title=&quot;&quot;
        src=&quot;/static/620735a45715fb0e275fe5c2a955bb53/fcda8/claude-ai-reddit-2.png&quot;
        srcset=&quot;/static/620735a45715fb0e275fe5c2a955bb53/12f09/claude-ai-reddit-2.png 148w,
/static/620735a45715fb0e275fe5c2a955bb53/e4a3f/claude-ai-reddit-2.png 295w,
/static/620735a45715fb0e275fe5c2a955bb53/fcda8/claude-ai-reddit-2.png 590w,
/static/620735a45715fb0e275fe5c2a955bb53/efc66/claude-ai-reddit-2.png 885w,
/static/620735a45715fb0e275fe5c2a955bb53/c83ae/claude-ai-reddit-2.png 1180w,
/static/620735a45715fb0e275fe5c2a955bb53/52ab5/claude-ai-reddit-2.png 1420w&quot;
        sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Meanwhile, I’ve been using Codex 5.X models for a few months, and I have really
enjoyed using them. I haven’t really many, if any, issues with how the models work.
In projects using technologies like NPM that I’m very familiar with, it’s been a
great companion. In projects that use technologies I’m not nearly as familiar with,
like iOS development, agents have been able to help me go from having 0 code written
up, to having something workable and iterable within a matter of hours. The skills
that I lack are what these coding agents are able to help me make up for in my overall
skillset as an engineer.&lt;/p&gt;
&lt;p&gt;What I do notice, however, is how much these models really end up being more of an
&lt;em&gt;extension&lt;/em&gt; of me as opposed to being an omipotent being of infinite knowledge. One
fairly discreet example is how models approach creating great UI/UX. I will be the
first person to admit that I am nowhere near the best at creating intuitive and
friendly user experiences. I do know how to work off of mock-ups and discreet designs,
and I can be an amazing partner to any UX designer. However, it would take me more
time to create great user experiences without the help of a designer or a design
system to work off of, agent or not.&lt;/p&gt;
&lt;p&gt;I’m sure if I was better at crafting wonderful user experiences, I could tell
an agent what I wanted and how to accomplish it. Heck, even if I was able to create
a good mock-up or two myself, I could ask Codex to work off of a
&lt;a href=&quot;https://developers.openai.com/codex/workflows#prototype-from-a-screenshot&quot;&gt;screenshot of a prototype&lt;/a&gt;.
I didn’t even know until very recently that Codex was even capable of this!&lt;/p&gt;
&lt;p&gt;Along the way, there are some tips and tricks that I’ve learned that either you’re
going to read and say to yourself “wElL dUh, tHis iS ObvIoUs” or “huh, I haven’t
considered that before, maybe I will now”. Hopefully these will be useful to you:&lt;/p&gt;
&lt;h2&gt;Context Matters&lt;/h2&gt;
&lt;p&gt;Providing your tools with as much context as possible is going to always yield
better results in the long run, whether you’re working with existing or new code.
I have yet to fully adopt planning mode in a lot of agents because… Well, frankly
I find it more useful to just give it a list of instructions and functionality that
I want. I think if I actually wanted help with actually planning out a new project,
I’d likely try it, but more often than not I usually have a pretty good idea of what
I want the agent to work on. I’ll typically list everything out that I want and
allow the agent to iterate on it.&lt;/p&gt;
&lt;p&gt;For example, if I was going to create the internet’s favorite CRUD starting project,
a TODO app, I’d likely start building the app by using my framework of choice’s Getting
Started guide to create a scaffold. I’ll explain in the next section why I might do
this. So I might start out using &lt;code class=&quot;language-text&quot;&gt;npx create-next-app&lt;/code&gt;, just as an example, if I wanted
to use Next.js. Depending on what else I think I might need, like Auth, a DB, and styling,
I might also go and do some research to see what else I could take advantage of to speed
up development. Tailwind and Supabase are two pretty popular options, so I might craft up
a prompt telling the agent what I want the app to do, and what I want it to use to
accomplish my goals:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&gt; I would like to create a small project that will display a web page that shows a list of TODOs:

* The app&apos;s landing page should prompt the user to login if they haven&apos;t already. There should also 
be a button prompting them to sign up if they do not have a login.
* Once logged in, the user should see their list of things to do. If they don&apos;t have anything, 
write a motivational message encouraging them to start adding things.
* Allow the user to add something to do, and for each list item, allow them to click it to navigate 
to a page where they can update the item with more details.
* Allow them to put a due date, a more detailed description, a priority, and an emoji that will display 
on the TODO list next to the item.
* On the TODO list page, allow the user to mark items complete. When they mark an item complete, display a 
confetti animation. Keep completed items at the bottom of the list.
* After 30 days, archive completed and deleted items from the list and keep them in a separate 
section of archives where they can see them, but not interact with them.
* Allow the user to sort the list by due date, priority, and alphabetically.

I want you to use Tailwind for styling, react-icons for any icons you might need, assume that this app will be deployed on 
Vercel using Next.js, and use Supabase for Auth and DB.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This all assumes that you have a good idea of what you want your architecture to look like,
and you know what services you want to take advantage of. If you don’t, the other thing you
could do is use a combination of ChatGPT chat and deep research modes to perform an
analysis of what services might be a good fit based on what your requirements are. Both
ChatGPT and Claude offer research modes in their chat clients if you have a subscription
that allows you to use their coding agents too.&lt;/p&gt;
&lt;h2&gt;Keeping Existing Tooling in Context&lt;/h2&gt;
&lt;p&gt;One thing I continue to find is that in some instances, coding agents don’t quite
understand that some source-controlled code is auto-generated by means other than
agentically, or that there are standard tools that frameworks provide to generate
necessary code, files, and configuration. This could either be in the form of
those tools existing at the beginning stage of a project, or during the development
of a project.&lt;/p&gt;
&lt;p&gt;In instances such as this, I tend to lean on using existing tooling first to
generate a scaffold, then turn to the agent to help with finite business logic.&lt;/p&gt;
&lt;p&gt;As an example, I’ve been using &lt;a href=&quot;https://www.openapis.org/&quot;&gt;OpenAPI&lt;/a&gt; for years
to help generate API specifications for my RESTful services, as well as to
generate clients. I’ve found that in some instances, rather than using OpenAPI
command-line APIs to generate a client, it tends to want to modify the client
as if it’s a hand-written file, as opposed to using other commands to generate
clients based on a spec.&lt;/p&gt;
&lt;p&gt;Another example: whenever I’m starting a new project, I notice that if I use
the agent to actually create the project scaffold, sometimes it ends up creating
something that is out of date, or it tries to create a project that under normal
circumstances is incomplete.&lt;/p&gt;
&lt;p&gt;In cases such as these, I may interrupt an agent in order to use existing tooling,
then turn it loose to help with the rest. Either that, or I’ll give it more explicit
instructions:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&gt; This repository contains a client package that is generated using OpenAPI. I&apos;ve 
pulled down the latest spec. Use `npm run generate:client` to generate the client 
package, then use `npm run build` to ensure that all the rest of the code still 
compiles.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Adding this kind of tooling to your repo’s instruction files (like &lt;code class=&quot;language-text&quot;&gt;AGENTS.md&lt;/code&gt; or a
similar file) can help with ensuring your agents have context to what kinds of tools
it should use for certain tasks. Balance this with the time it takes you to just run
these tools yourself of course, but if you’re running a lot of these commands, it may
behoove you to teach the agent to use them instead.&lt;/p&gt;
&lt;h2&gt;One-Shotting Using Mentions&lt;/h2&gt;
&lt;p&gt;Agents fairly often might just try to generate code using practices that the underlying
model has been trained on. For many teams, this isn’t always the desired behavior.
Sometimes a long-established pattern or practice is what is desired over whatever the
model thinks is best.&lt;/p&gt;
&lt;p&gt;Let’s say you’re working on a RESTful service, and you want to use an agent to help you
add some new functionality to it. There are already some well-established patterns for
breaking down how the code is structured from the routing, down to how the data model
is built. You might have a prompt like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&gt; I need a new set of endpoints built out to help manage TODOs in this service:

* Create CRUD endpoints for all the TODOs.
* Create a data model for the TODOs that relates many TODOs to one user.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Every online course that teaches you how to use Generative AI teaches the
concept of zero-shot, one-shot, and few-shot prompting. The above prompt is an
example of a zero-shot prompt: you’re telling the model what you want, and you’re
going to let it decide how it does it. You’re not providing any examples of
existing code.&lt;/p&gt;
&lt;p&gt;Will this produce code that works? Possibly. Will the code follow best practices
that are present in the repo? Probably not. The model is very likely to yolo in
what you’re asking for without giving a second thought to everything else around
it. It very well might miss important considerations like security, telemetry,
and performance optimizations already present in other parts of the code.&lt;/p&gt;
&lt;p&gt;You can help aid the model by providing it with more context in the form of a
one-shot or few-shot prompt using file mentions. File mentions allow you to refer
to existing code in your instructions. By adding mentions to a prompt, you’re
turning your existing zero-shot prompt into a one- or few-shot prompt, contextually
providing examples that the model can leverage to generate better results. The
above prompt might change to:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&gt; I need a new set of endpoints built out to help manage TODOs in this service:

* Create CRUD endpoints for all the TODOs. See @src/api/controllers/foobars.controller.ts 
for an example of how to create a controller for TODOs. Ensure you add all the same 
logging and security annotations to the controller methods that are present in the 
foobar controller to the new one.
* Create a data model for the TODOs that relates many TODOs to one user. We use Prisma 
for our ORM, so I&apos;d recommend adding the new schema to @src/prisma/schema.prisma 
and running `npx prisma generate` to generate the new model. Ensure that the model has 
row-level security built-into it, like we did with the foobar migration: @src/prisma/migrations/20250116000000_add_all_teh_foobars/migration.sql&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Zero-shot prompts, I have found, are really not as useful if I’m working with an existing
codebase with well-established patterns and practices. If you want the model to be more
creative in how it solves a particular problem, zero-shotting may be a better route to
take, otherwise it might try too hard to use the context provided from a few-shot prompt.&lt;/p&gt;
&lt;h2&gt;Dependency Upgrades&lt;/h2&gt;
&lt;p&gt;Technical debt still runs rampant in many organizations. Outdated dependencies are
not only ticking time bomb for security vulnerabilities, but as dependencies evolve,
they become beneficial for your end-users in the form of added stability, performance,
and features.&lt;/p&gt;
&lt;p&gt;You know what really sucks about outdated dependencies though? Especially in Node projects?
Updating all of them. I thought updating dependencies in Java was a pain whenever I was
knee-deep in Maven dependency hell. I still to this day &lt;em&gt;hate hate hate&lt;/em&gt; updating any
frontend Node project dependencies, because pretty much everything is bound to break
when you do. Agents, though, are able to iterate on upgrades, linting, building, and
test runs until everything just works™️.&lt;/p&gt;
&lt;p&gt;In many projects, I’ve asked agents to help upgrade dependencies while ensuring that
all of my quality checks still pass. For example, earlier today I asked Codex to
upgrade all the dependencies for my blog:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;If you were to run `npm outdated` you&apos;ll notice that several dependencies in this project are outdated. Please upgrade the 
dependencies in here to the latest for each, ensuring that everything will compile still by the end using `npm run build`.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Recently, the company I work for also went through a rebranding, which meant
that our design system also went through a pretty drastic change. I had gone through
and updated one of our core component libraries to match this new design system and
include updated branding. As part of this, I had also written documents regarding
upgrading from older versions of this library to the new one in the form of markdown.&lt;/p&gt;
&lt;p&gt;Normally, taking an app from an older version of this library to the new one would have
required a lot of manual rework of existing components that consumed that library. However,
I was able to migrate an older app to using a new version of this library using Claude
through Github Copilot CLI by copy-pasting much of the migration documentation I had written
into the prompt I had made to tell it to upgrade the other dependencies in the project.&lt;/p&gt;
&lt;p&gt;Claude, with a little bit of handholding, was able to upgrade the dependencies, as well as
use the context from the documentation I wrote to successfully migrate the app to utilize
the new branding and design within our core component library. I got a bit scared when it
started to think that it would be a good idea to temporarily disable the script we had that
used eslint to lint our code… But after a few more explicit prompts and guidance, it was
able to get the linting working again.&lt;/p&gt;
&lt;p&gt;For shared components and libraries, this recent experience made me realize just how important
documentation is to a project: if I hadn’t written any of those documents explaining how to
upgrade from an older version to the newer version, this process would have been a lot more
painful: Claude would have had to make more assumptions about the code and the libraries
than it had to previously, and likely would have ended up making more mistakes than it would
have without the documentation.&lt;/p&gt;
&lt;h2&gt;Tooling Preferences&lt;/h2&gt;
&lt;p&gt;Speaking of the good ol days of coding by hand: I remember while working at Cerner,
every dev and their mother had their preferences of IDEs/editors they swore by. All
the Rails folks used Sublime. Java devs were all split between IntelliJ and Eclipse.
.NET Devs didn’t even touch their code unless they had a license to Visual Studio
Enterprise. When teams started integrating Node into their codebases, everyone started
out using editors like Sublime or Atom until Microsoft released VS Code.&lt;/p&gt;
&lt;p&gt;I think what we’re seeing in the industry now with agents is akin to the days of
arguing which editors were supreme! There are people who swear by Claude Code, others
who only use Codex, and there are growing numbers of people who prefer to have access
to several models and agents through subscriptions to Github Copilot, Cursor, Windsurf,
or Antigravity.&lt;/p&gt;
&lt;p&gt;In deciding which agent I wanted to start using, I actually had Claude and ChatGPT
perform web research and sentiment analysis on which subscription might be better.
Considering all the responses that Claude and ChatGPT gave me, I ended up subscribing
to ChatGPT. Through continued use and experimentation, I’ve found that Codex not only
works well for what I want it to do, but I also find it behaving more efficiently than
other models have. The behaviors of how it executes really matters in terms of being
able to autonomously work towards “completeness”, and I’ve noticed that while the quality
of work that each model produces is pretty comparable, how each agent behaves can
vary greatly:&lt;/p&gt;
&lt;p&gt;Typically if I have a list of instructions or requirements that I want the agent to
follow, Claude and Codex tend to take very different approaches to completing things.
Pretty much every model will take my instructions and compile it down into a plan of
tasks that it wants to perform. It basically goes through it’s own little planning mode
before executing. No biggie.&lt;/p&gt;
&lt;p&gt;What &lt;em&gt;is an issue&lt;/em&gt; though is the continuity of execution: despite the model creating
it’s own plan of tasks, Claude tends to do one or more subsets of the plan and then
it just… Stops? It’ll complete some things and then just say at the end something
like:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Ok, so here&apos;s all the stuff I did:

// insert list of accomplishments

Whenever you&apos;re ready, let&apos;s move onto the other tasks that you&apos;ve asked me to do!&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;But… But… But I do want you to do the rest of that stuff! I’m not ready &lt;em&gt;later&lt;/em&gt;,
I’m ready &lt;em&gt;right now&lt;/em&gt;! What do you think you’re doing? What’re you stopping for? The
biggest value-add of an agent is to delegate things that it can automatically do for
you so that you can spend more time on other things that it cannot. What’s with
stopping partway through and waiting for me to type &lt;code class=&quot;language-text&quot;&gt;continue&lt;/code&gt; and hit Enter?&lt;/p&gt;
&lt;p&gt;I will say though: this is an issue that I’ve yet to run into with Codex. Codex as a
coding agent is pretty good at coming up with a plan and executing it continuously. In
contrast to my experience with Claude, I once asked Codex to generate some files for
me that hepled generate levels for a game I was working on. It created a script to
generate the levels instead, but what it did after that was pretty interesting: it
actually ran the script, which took several hours to execute, and verified the
results. I don’t believe I ever had to tell it to continue before.&lt;/p&gt;
&lt;p&gt;I will reiterate though that so much of my desire to continue using Codex over
Claude is &lt;em&gt;preference&lt;/em&gt;. I don’t think that Claude is inherently bad as far as
coding agent models go. In fact, from my usage of both, Claude can hold it’s own
against Codex in terms of quality and internal design. The best advice I can really
offer regarding preference is to just try out new models and agents and tools as
they become available, and see which ones work best for your workflow, use-cases,
and team.&lt;/p&gt;
&lt;p&gt;With how rapidly these models are evolving, the tools are changing and getting better
and easier to use, and how the industry continues to adopt them in new and innovating
ways, engineers will first and foremost keep their fingers on the pulses of the
industry to understand how these tools are changing and evolving and what is becoming
available. Secondly, they’ll need to have more fluid preferences than they previously
have had.&lt;/p&gt;
&lt;p&gt;I’ve used VS Code-based editors for nearly a decade. In contrast, I’ve used several
different coding models and agents. The code didn’t change. The frameworks and libraries
didn’t change.&lt;/p&gt;
&lt;p&gt;The tools changed. I’ve changed along with them.&lt;/p&gt;
&lt;p&gt;The tools will continue to change. I’ll continue to change along with them.&lt;/p&gt;
&lt;h2&gt;Buying Time Back&lt;/h2&gt;
&lt;p&gt;Beyond the terminal, outside the editor window, and beyond your hard drive, there are
still other things as a software engineer that you’re responsible for. Design,
documentation, backlog grooming, code reviews, &lt;em&gt;&lt;strong&gt;yourself&lt;/strong&gt;&lt;/em&gt;, etc. The time you save
automating your coding work can be used to propel you in so many other ways.&lt;/p&gt;
&lt;p&gt;When was the last time you had an “and” project that you really thought would add
a lot of value to your organization? When was the last time you felt like you had any
time to actually dedicate to it? I know for a fact many of you out there probably have
something you want to learn more about. Take the time you aren’t coding to do the more
manual parts of your work, to learn or experiment with something new, to collaborate
with or provide mentorship for your colleagues, or read one of those books you bought
but never finished because you had too many features with approaching deadlines you
needed to ship.&lt;/p&gt;
&lt;p&gt;I talked about this in a previous post, but one thing you’ll need to make sure you do
is spend more of your time reviewing code. Not just other people’s code, but also the
code that you’re delegating to agents. I still fall into this trap and I have to keep
reminding myself that as good as some of these agents are getting, they still make
mistakes that could be resolved simply by reviewing the code and making a few edits
before sending it to the rest of your team.&lt;/p&gt;
&lt;p&gt;If you are working on something that might require changes across multiple codebases,
using agents is a great opportunity to delegate the changes to multiple agents to
coordinate changes across multiple repositories. If you have multiple tasks you’re
assigned across multiple repos, this is an even greater opportunity for delegation!&lt;/p&gt;
&lt;p&gt;The only thing I haven’t done yet is delegeting multiple sets of changes to the same
repository without having multiple copies checked out at once. If I figure out how to
do this while trusting an agent with &lt;code class=&quot;language-text&quot;&gt;git&lt;/code&gt; access, I’ll share later 😅.&lt;/p&gt;
&lt;h2&gt;That’s a Wrap!&lt;/h2&gt;
&lt;p&gt;Well that was a lot of thoughts I spewed for a Saturday. I hope you found some of this
helpful, interesting, thought-provoking, or garnered some other kind of positive reaction
from you. Wherever you are in your AI-fueled journey, I hope this post has motivated you
to continue to learn and develop your skills!&lt;/p&gt;
&lt;p&gt;If you have follow-up comments or questions and you made it this far into the
post without bouncing, you can always reach out to me on any of the social medias
at the bottom of the page!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Review Your (AI's) Code]]></title><description><![CDATA[It’s no secret that Generative AI has become a massive trend in software
development. My own experiences have evolved over time as tools…]]></description><link>https://jvarness.blog/review-your-ais-code/</link><guid isPermaLink="false">https://jvarness.blog/review-your-ais-code/</guid><pubDate>Fri, 15 Aug 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;It’s no secret that Generative AI has become a massive trend in software
development. My own experiences have evolved over time as tools have become
increasingly more powerful.&lt;/p&gt;
&lt;p&gt;Two years ago, everyone started out using ChatGPT as a replacement for
StackOverflow. I’d be lying if I said I didn’t use it to better understand Ruby
code (and to write some of it for me 🤣). We could copy/paste prompts into
a web interface with our code in order to make it write test cases for us.&lt;/p&gt;
&lt;p&gt;As time went on, the tools just kept getting better. I remember the first time I
used Github Copilot and I thought to myself “oh this is really cool”. Watching
those faint lines of code appear after things I type, the algorithm trying it’s
damndest to predict my next move, and having it come up with the right answer
sometimes, really started to show me how much more productive I could be with
these tools.&lt;/p&gt;
&lt;p&gt;Just when I thought the tooling couldn’t get better, I downloaded Windsurf and
started seriously using it. Yea yea, I know, Cursor is a thing, but I also use
Bulma instead of Tailwind for everything, ok? I go against the grain sometimes.
As I’m writing this post, I’m actually writing it in Windsurf. Don’t worry: I
didn’t have Windsurf write most of this for me. In fact: I’m not really sure I
can recommend using Windsurf to write a blog post for you. As I’m typing along
and watching Windsurf predict what I’m going to write, &lt;del&gt;it’s not as good as
predicting what I’m going to write. It’s not as good as
predicting what I’m going to write.&lt;/del&gt; you can see that those last few tabs
didn’t quite convey anything coherent with everything else I’m talking about,
and… For some reason it repeated itself?&lt;/p&gt;
&lt;p&gt;Beyond that though, Windsurf has been helping me immensely with work: I’ve been
using it to rapidly prototype projects that I’d normally only have on the back
burner, and automating more tedious tasks while taking time to review other
team members code or updating JIRAs or working on designs.&lt;/p&gt;
&lt;p&gt;However, one thing I have noticed in the work I produce using these tools is that
I tend to not take enough time to review whatever the AI model is creating. There
are sometimes bugs in the code that’s been generated, or typos, or something else
in the code is just not correct, and if I took a little more time to review it
before putting it up for review, I would be able to avoid a lot of the thrash of
receiving comments and addressing them.&lt;/p&gt;
&lt;p&gt;I had a bit of an experience like that this week, and it’s made me take a pause
regarding how I approach code reviews.&lt;/p&gt;
&lt;h2&gt;How I Used to Approach Code Reviews&lt;/h2&gt;
&lt;p&gt;The first time I ever participated in a code review was when I was working for
Cerner back in 2014 in their DevAcademy training program for new hires. Code
reviews were a really big focus for all of us in training: it was the first time
that so many of our technical skills and communication skills were put to the test.
Do you want to be able to close a task out soon? Gotta get your code up for review.
Hope to ship that feature you’ve been working on all sprint? Go get them approvals.&lt;/p&gt;
&lt;p&gt;Code reviews for a long time have acted as a litmus test: you can’t close a task
if your code isn’t merged, and you can’t merge your code until you get all the
necessary approvals on your review(s), and you can’t get those approvals until
you address all the feedback. If it at least passes the vibe check with the rest
of the team, you’re good to go. There’s a lot of other quality gates teams can
put in place like test coverage and static analysis tools, but code reviews have
been the engineering team’s last line of defense to catch bugs before pushing
them to the rest of the business (QA, Security, Support, etc.).&lt;/p&gt;
&lt;p&gt;In the past, when I’ve put code up for review that simply wasn’t ready to be
shipped, it either came down to a lack of understanding of what problem I was
trying to solve, or it was more of a rushed job, and in either case, it became
obvious to myself and any other reviewers that whatever I put up wasn’t quite
“done” yet. Because of this, and for as long as I can rememeber, I &lt;em&gt;always&lt;/em&gt;
tried to ensure that I was &lt;em&gt;absolutely sure&lt;/em&gt; that whatever I was offering up
in a review was ready to be shipped &lt;em&gt;now&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;As I began to mentor new engineers throughout my career, that’s also the same
advice I gave them: if you want others to review it, you better make sure you’re
ready to ship it. If you wouldn’t ship it today without being completely
confident that it’s ready to go, don’t even put it up for review. Part of that
stemmed from the fact that there used to require a lot of manual effort to even
write the code to begin with, and that you as the author understood &lt;em&gt;what&lt;/em&gt; that
code was doing, and &lt;em&gt;why&lt;/em&gt; you chose to make certain implementation choices.&lt;/p&gt;
&lt;p&gt;I still stand by that advice, but I’ve come to realize that when I’m using AI
tooling to write code, I need to take more of my own advice.&lt;/p&gt;
&lt;h2&gt;How I &lt;em&gt;Now&lt;/em&gt; Approach Code Reviews&lt;/h2&gt;
&lt;p&gt;What I’ve come to learn from using AI is that it’s the same as using any tool in
software development: you have to learn how to use it effectively. Some folks use
AI and they’re really great at getting their desired end-result from it. Others
take vibe-coding to an almost unhealthy level, simply trusting what’s generating
will work without reviewing the changes themselves.&lt;/p&gt;
&lt;p&gt;On the other side of that adoption spectrum, there are folks who outright refuse
to use AI tools, either due to skepticism that what they’ll get is awful, or
because they truly believe they are much better at writing code than AI is.&lt;/p&gt;
&lt;p&gt;What I find to be best for myself is to integrate AI tools into my daily coding
workflow, either when I get stuck on something, or if I want to save myself time
with creating files that AI can create based on documentation I created, or if I
want to go from nothing to POC on something as quickly as possible. Of course I’ll
have to clean things up myself later, and put all the proprietary knobs and bits
into the places I need them in, but I find that I’m able to accomplish a great deal
more with this little pair programmer on the side of my editor than I could if I
was researching and creating all of the code myself.&lt;/p&gt;
&lt;p&gt;But therein lies the issue: just because the tool made it doesn’t mean it’s
&lt;em&gt;ready for prime time&lt;/em&gt;. In more recent examples at work: I had it generate a bunch
of files for me based on documentation that I had the rest of my team reviewing
over the last week. It was able to do a decent job, but after I put up all the
files for review, I realized something:&lt;/p&gt;
&lt;p&gt;I didn’t really review any of the files myself, and in doing so I put a lot of
undue burden on other team members.&lt;/p&gt;
&lt;p&gt;I’d say the tools got me about 65-70% of the way there, but there were so many
little things I missed if I would have just taken the time to review it myself.
I could have gone in and manually edited each file to make sure each one was
correct. Heck, I probably could have told Windsurf what it had done wrong and
it might have gone and done it for me.&lt;/p&gt;
&lt;p&gt;What I’ve realized in using these tools is that my code review process needs to
change. I need to pair with my newfangled editor, not just let it take the wheel.
Each line and statement should be scrutinized, and not assumed to be correct.&lt;/p&gt;
&lt;p&gt;I’m realizing that I need to reverse the principle a little bit: with all the
time saved in implementing something, I need to dedicate a little more time to
reviewing the code &lt;em&gt;myself&lt;/em&gt; before it’s reviewed by others. After all, I’m still
trying to ship something, and if it’s not ready, someone else is gonna catch it,
and that’s not really fair to whoever that someone else is.&lt;/p&gt;
&lt;p&gt;There’s an entire tab in VSCode/Windsurf/Cursor that I’ve always had that allows
me to see git diffs of all the changes in the current working branch of code I’m
working on. I’ve literally never used it though, because most of the time I’m
using the Git CLI for everything. Some people might like using a visual client
for Git, but I can’t stand them. I find them much harder to use than the CLI.&lt;/p&gt;
&lt;p&gt;However, one thing that the CLI really lacks is a good way to quickly review
diffs of unstaged changes. Much like how we typically rely on Github or Gitlab
PRs/MRs to review code, I’m starting to realize that I should be picking through
diffs of what Windsurf is helping me write before I send it off to the rest of
the team. I think that little tab in the editor is going to start getting a lot
more use from me!&lt;/p&gt;
&lt;p&gt;So those are all my thoughts on how I’m going to start changing my workflow.
Windsurf has been an absolute pleasure to use, and I’m getting a ton of value
out of it, but no matter how fast I’m able to move with it, I’m realizing I
can’t speed up at the expense of slowing everyone else down.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Pellet Grill Pulled Pork]]></title><description><![CDATA[What You’ll Need Ingredients  1 pork shoulder (a.k.a. Boston Butt)

 Approx. 1/4 cup yellow mustard

 BBQ Rub of your choice (see below for…]]></description><link>https://jvarness.blog/recipes/pellet-grill-pulled-pork/</link><guid isPermaLink="false">https://jvarness.blog/recipes/pellet-grill-pulled-pork/</guid><pubDate>Sun, 17 Nov 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 590px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/1db9b0577d4a172684a80af8f11dbd2d/00d43/finished-pulled-pork.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAIAAABr+ngCAAAACXBIWXMAAC4jAAAuIwF4pT92AAADH0lEQVR42iWT208jVQDGJwvtzJlzmZkzZ2Z6g9LSlk5nmOm2ZaZNC7i2LBd1BVxrZSUssFJbCwgYZC/ZNSJBHzYxatT4Ykx8MBv/SM9C8ns4L7/vfMn5joCZwSGMYaojjWKFYIIhB0EZQQChJAMJABFIUUnkRMToeDRyi4B0E+smYYbCGNF5BCWqwiO4L2MEMZLxbYrMU3jEbcpthCBz07DUt5g3GESnhGqYalBVkaJARZEVLCEkQQiQDHiRmxTuC0A3IbP0eNxMJjSTV2Dc10xDsxg/3wFwXEayokgYi9x/C5R4i5sKgswswCwlFjdTqalcJqz5WxvLG51mv/fALeY7C2HJzkcRGQMwIiMR4ShEnAgAHEE2Y9yXqBmE1YPu+8PNlavB9vn25o/nh+XpiV8vRj98tfv5w5Wab1PGxgCK3vgRGY4DWQCGNa7QXKl0/fLZaLt3fXb4y3Dr97Mv/nx6dPqw/c/ls53V9t7yO5ej3edPuq2wMgaJSFQewX3BnM6lbXu3++HLYf/i4OBs+7MXj3o/Hw3/fX393+vLN8+Pr/r716Mvr4aDb3e6r/Z7q61QYaaoqCIhQnrWq9aDk48ffLLYOu9uDFbubzXD4/W17wdP/nhx/tvXJ38//ebNq4vvuuunH6ydLs2fdlf8mYk7MgKqImRcb7JY6tS8x4vhyfr90Wp71Jn/62zw09HeoP3uljf7eL51uLrUX5jrBXNrrl2I65aliZgPgQhZz0/b7mRhZjPwHjUrO81wNwwG1cpxu77fKA8XGnuh3283P637QTYdj8X442NVhQRx+M2zGcedKpXKnlPOZ+YyU0uucy+dfC+f7frOR25hr+7uNIKOU6jlEhpjSNM1yyJU53MQ0iXHqVbmmg3b91OZDIsndMPITSTzk2k+VAvjStwoMnZ3MplNxqhlQVWDGkVUV0yTy65dqTpB4AV15241WyymZ2w9kdJjcYXqAJMoQCJEKjNkjRLD5L8I8MGpioixMO2Vs7PlmUqtubzmNVqVxXuFciXn+pmik8pkjUSCz57oBrVifPmIUqwb/FpIdYmQ/wH1TpITGJRLdwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;A pork shoulder after having sat in a smoker for over 9 hours&quot;
        title=&quot;&quot;
        src=&quot;/static/1db9b0577d4a172684a80af8f11dbd2d/fcda8/finished-pulled-pork.png&quot;
        srcset=&quot;/static/1db9b0577d4a172684a80af8f11dbd2d/12f09/finished-pulled-pork.png 148w,
/static/1db9b0577d4a172684a80af8f11dbd2d/e4a3f/finished-pulled-pork.png 295w,
/static/1db9b0577d4a172684a80af8f11dbd2d/fcda8/finished-pulled-pork.png 590w,
/static/1db9b0577d4a172684a80af8f11dbd2d/efc66/finished-pulled-pork.png 885w,
/static/1db9b0577d4a172684a80af8f11dbd2d/00d43/finished-pulled-pork.png 1000w&quot;
        sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;What You’ll Need&lt;/h2&gt;
&lt;h3&gt;Ingredients&lt;/h3&gt;
&lt;p&gt;&lt;input type=&quot;checkbox&quot;&gt; 1 pork shoulder (a.k.a. Boston Butt)
&lt;br/&gt;
&lt;input type=&quot;checkbox&quot;&gt; Approx. 1/4 cup yellow mustard
&lt;br/&gt;
&lt;input type=&quot;checkbox&quot;&gt; BBQ Rub of your choice (see below for recommendations)&lt;/p&gt;
&lt;h3&gt;Optional Ingredients&lt;/h3&gt;
&lt;p&gt;&lt;input type=&quot;checkbox&quot;&gt; Rolls or buns to serve it on
&lt;br/&gt;
&lt;input type=&quot;checkbox&quot;&gt; Sauce to serve on the side
&lt;br/&gt;&lt;/p&gt;
&lt;h3&gt;Recommended Tools&lt;/h3&gt;
&lt;p&gt;In order to precisely cook the pork to the desired temperature, it’s important that you have a meat thermometer.
Also, a pellet grill would be good!&lt;/p&gt;
&lt;h2&gt;Recipe&lt;/h2&gt;
&lt;ol start=&quot;0&quot;&gt;
&lt;li&gt;Calculate how long your pork shoulder will need to cook for, and ensure you will have enough time to cook it prior to starting. For every pound of meat, you should expect to smoke it for about 2 hours. The pork shoulder in my photos is about 4.5 lbs, and it took roughly 9 hours to cook thoroughly.&lt;/li&gt;
&lt;li&gt;30 minutes prior to when you need to start smoking the meat, take the meat out of the refrigerator, and start preheating your grill to 225 °F.&lt;/li&gt;
&lt;li&gt;Place your pork shoulder on a cutting board, with the fat cap side face-up. Use a paper towel to dry off the surface of the meat, then score the fat cap.
&lt;ol&gt;
&lt;li&gt;The best way that I’ve found to do this is to cut in only one direction (not a checkerboard style), 1 inches apart, and deep enough where your cuts are getting through where the fat cap meets the lean.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Rub the mustard into the pork shoulder, creating a thin layer of binder all around the meat, being sure to rub mustard in between the cuts. Then, generously sprinkle your choice of BBQ rub onto the pork shoulder, covering all sides of the meat.&lt;/li&gt;
&lt;li&gt;Insert a meat thermometer into the middle of the pork shoulder.&lt;/li&gt;
&lt;li&gt;Allow the meat to sit on the cutting board for 15-20 minutes while the smoker is preheating (this will allow the meat to warm up a little bit and for the seasoning to bind to the meat)&lt;/li&gt;
&lt;li&gt;Once the grill is preheated to 225 °F, transfer the pork shoulder to the center of the bottom rack of your grill, with the fat cap of the shoulder facing up.&lt;/li&gt;
&lt;li&gt;Smoke the shoulder for approximately 2 hours for every 1 lb of pork, or until the pork reaches an internal temperature of 195 °F.&lt;/li&gt;
&lt;li&gt;Remove the pork shoulder from the grill, and transfer it to some kind of dish with walls, like a glass baking dish or a disposable aluminum dish. Let it sit in the oven or microwave to rest for about 10 minutes.&lt;/li&gt;
&lt;li&gt;Shred the pork with a couple of forks inside of the dish it’s currently sitting in and enjoy!&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 590px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/c21a293b000dc0f66ffd03a29e98c47d/00d43/served-pulled-pork.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAIAAABr+ngCAAAACXBIWXMAAC4jAAAuIwF4pT92AAADnklEQVR42gGTA2z8AF9WSYiEfJ55eLFkZo1XRn1URZpkVqZ1ZItlUqZ9ZsKfgoNWRpZiR+/UodPBrsK6uKKGgqVPXJpWV4ZXTgBXKCKOLi2kISO0Hx+PTjqedF+TXE2LX1JsSjtaOi2RZlVySz9zRTmyiW/LoofizKPXupnFqYi9pIOWZVsAhBgalhwdrR4gzDIyt4RolWpOcEk1SC0fVTYpTCQcZkI3RSYhPh8dXTkvkmZOt5BugkwypnxVs5t0iGBUAJIeHqkgIcAiI+ahiejXrZljS2w6ImhPNE4tIVcfF2Q+LkorIj8jH2A4K59vWoRWSWI7L39dSoptWINeXACoISK2FBnUa17x6sDHqoLBo3q2lWuukm2ehWl4VDyFXkV9WD5wSTafaVqYYldkPzR4VEGEYU52VkiKY1YAjSYckxIRtVpQtY5tilMkfls2n3lWqX9j9+Oy6tKjyKR5p3xZZjkockM4TiohdVI/kGdPcEs3a008lHxqAIRKJZluOJ9hNGk4H1ksEk0nC00VDHY6J6iGZMCifODEl8mpfXJMMmpQOGFHNpRqVHhSPzcbEoBpVKSLdgCANRyGWimidjlsRh9OJxFOJg5kMRmBTiRnNxZ1RyCebkaub1fpy57cw5Sne2KJW0hhQTJjTTqYeGOXaFgAfRkRgUwgVSkUeisbuIZJa0EbhFkyp3c5QRgCf1YwflQqejsikW1QwqmEkmJPjmZSu596t6GBkkI4bhANAIMOD5BIKndLJYAmGnY8ImY9H5BlOIlfLToVBVk5ImQ8HpFlNFQkDlsnGoBJOLSLbtnFmaOCaGobF0oHBgCDEBCFNht9UiFjNhptJhxyQyRZMhRuSiVtRyVPKA93Rh2UYSyGPyCBDA+aGhqqQTemcVmKPzNXCwlJCggAhy0bm2k5ekghUh4KXCcWm203h10rjVsobz0YlV8rxZpipHVEjkImsikqshsdqBoaixMTVwkHSQgHRAcGAJFBJ8aXXZxlNGEvFJ1sOK9+P6hxOqRoM28qF31EHc2YXc6jaJwxIrYdIr4hILEgH5UZGFQKCUUHBj8GBQCZUTLMpmyMVy2SWSmpdTqKMBaeMySJUi9lJBVyQCGPUie/k1iROCOdDRK8IiG3IiKnHh5jDg1BBwY7BAQAhzUim2c/hj0klykZlDIZnBATsCAbeDoXVSMNgSEdpCYbmkMjliQbshsdtiMiriAgpB0fchYUQAUEOAMDtXpGSIdRB2kAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Pulled pork served on Hawaiian Rolls with a side of roasted potatoes&quot;
        title=&quot;&quot;
        src=&quot;/static/c21a293b000dc0f66ffd03a29e98c47d/fcda8/served-pulled-pork.png&quot;
        srcset=&quot;/static/c21a293b000dc0f66ffd03a29e98c47d/12f09/served-pulled-pork.png 148w,
/static/c21a293b000dc0f66ffd03a29e98c47d/e4a3f/served-pulled-pork.png 295w,
/static/c21a293b000dc0f66ffd03a29e98c47d/fcda8/served-pulled-pork.png 590w,
/static/c21a293b000dc0f66ffd03a29e98c47d/efc66/served-pulled-pork.png 885w,
/static/c21a293b000dc0f66ffd03a29e98c47d/00d43/served-pulled-pork.png 1000w&quot;
        sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;Easy, Simple, Delicious&lt;/h2&gt;
&lt;p&gt;For Father’s Day a few years ago, I was able to get my first pellet grill, and one of the very
first things I ever smoked on it was a pork shoulder! It’s one of my favorite things to make on
a pellet smoker, because it’s a good beginner recipe for those who are new to smoking meat, and
it tastes great.&lt;/p&gt;
&lt;p&gt;If you follow the above recipe, you should be able to make a delicious dinner for several people,
and I also have a few other tips that can help you on your journey to making some of the best meals
of your life:&lt;/p&gt;
&lt;h3&gt;“Look at me! I’m about to touch the buuuuutt!”&lt;/h3&gt;
&lt;p&gt;Sorry, but I love that movie. Anyway, when you’re going to the store to pick out your cut, you’re
going to want for specific cuts of pork. The cut you’re looking for goes by a couple of different
names, the two main ones I’ve seen are a &lt;strong&gt;pork shoulder&lt;/strong&gt; or a &lt;strong&gt;Boston butt&lt;/strong&gt;. They are
essentially pork roasts with the fat cap still on.&lt;/p&gt;
&lt;p&gt;Picking out a pork shoulder with a decent fat cap is one of the keys to success. A common phrase
used by many pitmasters across America is “fat is flavor”, which makes plenty of sense: it’s common
to put butter on things like steaks to enhance the flavor of leaner cuts of meat, or to wrap
brisket in butcher paper and beef tallow after it reaches a certain point in the cook. Sometimes
what folks might do when they’re cooking a pork shoulder is towards the end of the cook (maybe
about an hour or two before the shoulder is done) they will add butter and brown sugar to the meat,
place it in a metal container and cover it with tin foil to be able to lock in moisture and reduce
the amount of flavor lost from the butter or rendered fat dropping into the bottom of the grill.&lt;/p&gt;
&lt;p&gt;Why didn’t my recipe include that as a step? Well… One of the other things I don’t typically like
to do anymore is trim the fat cap of my pork shoulder. I used to, but I realized I was either
cutting away too much fat, or that my pulled pork wasn’t as flavorful with that fat missing.&lt;/p&gt;
&lt;p&gt;The other thing you want to be wary of is how large your cut is, how long it will take to cook, and
how many people you’re looking to feed. Typically, I will pick out a 4.5 lb pork shoulder. If I
have that cut on the grill and cooking starting at 8 a.m., after about 9 hours of smoking, 15
minutes of rest time, and a few more minutes of shredding, I can easily have it ready to eat by
5:30 p.m.&lt;/p&gt;
&lt;p&gt;If you think each person you’re cooking for could eat half a pound of meat, that’s 9 people you
could feed without leftovers. My wife and I end up getting &lt;em&gt;plenty&lt;/em&gt; of leftovers out of this dish
since it’s usually us and maybe a couple other people who eat with us.&lt;/p&gt;
&lt;h3&gt;It’s All in the Preparation&lt;/h3&gt;
&lt;p&gt;Once you’ve got your cut of meat, you actually need to prepare it! I’m now very particular about
how I prepare my pork shoulder, and it’s through trial and error… Well… Maybe not error as
much as experimentation until I find what I like best.&lt;/p&gt;
&lt;h4&gt;To Score, or Not to Score&lt;/h4&gt;
&lt;p&gt;Do you &lt;em&gt;have&lt;/em&gt; to score the fat cap of your pork shoulder? Absolutely not. Do I heavily &lt;em&gt;heavily&lt;/em&gt;
recommend you do? Yes, and I have a particular way I like to do it and I have my reasons for doing
so:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The best way that I’ve found to do this is to cut in only one direction (not a checkerboard style), 1 inches apart, and deep enough where your cuts are getting through where the fat cap meets the lean.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;How did I arrive at the conclusion that this was the best scoring method? Like I said, I have
experimented many times with different scoring methods, including not scoring at all. Here are my
findings:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;No scoring&lt;/strong&gt;: the meat towards the top of the fat cap is not as flavorful due to a lack of smoke penetrating that part of the meat, though the pork shoulder is quite moist.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bi-directional (checkerboard-pattern) scoring&lt;/strong&gt;: the meat towards the top of the fat cap has more smoke flavor, though the meat is a little less moist.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Scoring the meat in one direction at an angle (around 45 degrees, doesn’t have to be perfect) has
never failed me, and has produced the best tasting pulled pork.&lt;/p&gt;
&lt;h4&gt;The Condiments That Bind&lt;/h4&gt;
&lt;p&gt;While smoke provides the greatest amount of flavor to your pork, there’s also another major factor
that can change the flavor profile, and that’s how you season the meat. I’ve tried a few different
barbeque rubs, and I have really grown to enjoy Meat Mitch WHOMP! Rub, Meat Church Honey Hog, and
there is a local barbeque place in Kansas City called Jack Stack that sells an all-purpose meat
and poultry rub that tastes great.&lt;/p&gt;
&lt;p&gt;The best part about picking a rub is how much it can change your cook: Meat Church Honey Hog is
a much sweeter rub, while something like Meat Mitch or Jack Stack would be much more savory. In
combination with the smoke from whatever your pellets of choice are, the flavor profile of your
cook can change.&lt;/p&gt;
&lt;p&gt;Before applying any seasoning, however, it’s important to apply a binder so that you don’t lose
any of the seasoning prior to putting the meat into the smoker. For the purpose of this cook, I
used mustard. It’s &lt;em&gt;perfectly ok&lt;/em&gt; to use mustard for this, or you can use something like mayo.
Mustard is not normally a condiment I would put on anything because I just… Don’t like it at all,
but what I can tell you is that if you don’t like mustard, don’t be afraid to use it as a binder. I
can’t taste any mustard once everything is said and done.&lt;/p&gt;
&lt;p&gt;I’ve also seen online where people will use things like sriracha as a binder too, but I can’t
guarantee whether or not that will change the flavor of your cook. Mustard and mayonnaise typically
don’t have a very strong taste, but something like sriracha absolutely does. Maybe I’ll try it one
day, who knows.&lt;/p&gt;
&lt;h3&gt;Sitting and Waiting and Sitting…&lt;/h3&gt;
&lt;p&gt;One thing you can be sure about during this cook is that there will be a lot of downtime, but at
each stage of the game, it’s very important to allow time to pass:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Before putting the meat into the smoker and after applying bindings and seasonings, it’s a good idea to allow your meat to “sweat” in order to allow the seasonings and bindings to stick to the meat.&lt;/li&gt;
&lt;li&gt;During the cook, it’s important to just allow the pork shoulder to sit in the smoker and not fuss with it too much. Some people like to spray apple cider or something onto their pork shoulder&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;every couple of hours, but I have found in doing this that it doesn’t really affect things much.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I used to shred my pork shoulders &lt;em&gt;immediately&lt;/em&gt; after pulling it off the grill, and I would shred it on a cutting board. After allowing the shoulder to sit in the microwave for a few minutes in a pan and shredding it while it’s already in a pan, I’ve found that this prevents a loss of moisture that would otherwise just be all over the cutting board and countertop.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The downtime, however, is also what makes this recipe so easy: the majority of your time is just
spent monitoring the temperature of the pork shoulder. You don’t even need to open the lid of the
smoker for hours (unless you want to take pictures).&lt;/p&gt;
&lt;h3&gt;Serving Up Deliciousness&lt;/h3&gt;
&lt;p&gt;At this point the world is your oyster: you’ve got some perfectly cooked pulled pork in front of
you, and all that’s left is to serve it up! My favorite way is to just slap it on top of some
Hawaiian Rolls with some BBQ sauce and eat it like sliders, with some baked beans and some kind of
potato dish as a side. Pictured above is some french onion soup roasted potatoes, which is a really
easy side dish to make, and only takes 3 ingredients to make (that’s worth a post itself). You can
also serve it on a bun of your choice, or if you’re gluten-intolerant just by itself and eating it
with a fork.&lt;/p&gt;
&lt;p&gt;Usually this recipe will yield quite a bit of leftovers, and there’s even more that you can do with
any leftover pork that you have: you can either serve it the same way you ate it initially, or if
you’re feeling adventurous you can reheat it in a pan with some taco seasoning and make carnitas
with it!&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I hope you enjoyed this post! This is the first of many recipe posts that I hope to make in the
future, and if you did try this yourself, let me know how it went!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Adding Social Media Images to a Gatsby Site]]></title><description><![CDATA[When you post links on social media, sometimes the links generate a card that
looks really really nice. I say sometimes because… Well… This…]]></description><link>https://jvarness.blog/adding-social-media-images-to-gatsby/</link><guid isPermaLink="false">https://jvarness.blog/adding-social-media-images-to-gatsby/</guid><pubDate>Fri, 17 May 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;When you post links on social media, sometimes the links generate a card that
looks really really nice. I say sometimes because… Well… This site never
had good ones. I basically took that little “JV” logo I made in Gimp and set
that as the image. It &lt;em&gt;worked&lt;/em&gt;, but it wasn’t &lt;em&gt;great&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;When my links get posted online, I wanted to make sure that they looked at
least somewhat professional. I may be the only one ever posting them, but I
at least wanted them to look good! Not just a couple letters.&lt;/p&gt;
&lt;p&gt;So today, I’m going to tell you about the methods I researched to be able to
add social media images to my site, and how I landed on using a Gatsby plugin called &lt;a href=&quot;https://www.gatsbyjs.com/plugins/gatsby-plugin-satorare/&quot;&gt;gatsby-plugin-satorare&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Alternative Solutions&lt;/h2&gt;
&lt;p&gt;Let’s start off by pointing out how others solved this: there are quite a few
people who have solved this issue in the past, and many of the solutions
involve a similar process: build a component using React that you will
use in tandem with puppeteer to be able to render the images in a browser
window and then have it take a screenshot of the preview page. Here were some
of the posts that I had found:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.emgoto.com/gatsby-react-social-card/&quot;&gt;Emma Goto - “Generate custom social card images for your Gatsby blog”&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://danspratling.dev/blog/automatically-generating-a-social-image-in-gatsby&quot;&gt;Dan Spratling - “Automatic social images in Gatsby”&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.maxpou.fr/blog/generate-social-image-share-with-gatsby/&quot;&gt;Max Poutard - “How to generate social share images with Gatsby”&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These solutions work just fine, so if for whatever reason you don’t like the
way that I did this, you could try one of these. These solutions do have an
easy way for you to test out that your generator is working. The solution I
used did not have the easiest way of testing out that things worked, but
once I got it working it’s smooth sailing.&lt;/p&gt;
&lt;p&gt;In doing the research for which plugin/solution I ultimately wanted to use, I went to search for plugins on Gatsby for social images, and
&lt;code class=&quot;language-text&quot;&gt;gatsby-plugin-satorare&lt;/code&gt; came up as a potential option. It uses another library
from Vercel called &lt;a href=&quot;https://github.com/vercel/satori&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;satori&lt;/code&gt;&lt;/a&gt; that can take
JSX syntax and convert it into an image. They also have this really great
&lt;a href=&quot;https://og-playground.vercel.app/&quot;&gt;Playground&lt;/a&gt; where you can take the code you
want to use to generate the image and you can test out how the end product
looks. If I were you, and you want to use &lt;code class=&quot;language-text&quot;&gt;gatsby-plugin-satorare&lt;/code&gt;, I would
probably start there.&lt;/p&gt;
&lt;h2&gt;The OG Image Playground&lt;/h2&gt;
&lt;p&gt;Vercel’s OG Image Playground uses &lt;code class=&quot;language-text&quot;&gt;satori&lt;/code&gt; to be able to generate images using
JSX syntax. However, this library does have it’s limitations in terms of the
types of styling that it supports. Before diving into this, I would
recommend taking a look at the &lt;a href=&quot;https://github.com/vercel/satori?tab=readme-ov-file#css&quot;&gt;list of supported CSS properties&lt;/a&gt;
that you can use to create an image. One of the things I ran into when I was
doing this was that border styles weren’t working the way I expected them to.&lt;/p&gt;
&lt;p&gt;My blog uses border styles quite a bit to make some of the elements look like
they have slanted edges. For example, this is the style used in a couple of
different places on the site:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;css&quot;&gt;&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token property&quot;&gt;border-left&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 3em solid transparent
&lt;span class=&quot;token property&quot;&gt;border-bottom&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 3em solid #e5e02d&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;By using combinations of &lt;code class=&quot;language-text&quot;&gt;border-*&lt;/code&gt; styles and defining one as a solid colored
border and the other as a solid transparent border, you can cut a little of the
colored border off on either side. I wanted to use this type of styling in my
images, but &lt;code class=&quot;language-text&quot;&gt;satori&lt;/code&gt; doesn’t have the ability to do this when it’s generating
the images.&lt;/p&gt;
&lt;p&gt;If you wanted to try playing around with this effect, try heading to this
&lt;a href=&quot;https://codepen.io/jvarness/pen/ExJqKVL&quot;&gt;codepen&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you were to try this same effect in the playground, however, you would
notice that this simply doesn’t work. I’m assuming this is because of how
satori works: it converts JSX syntax into an SVG, and I’m guessing that the
translation from CSS styles to SVGs isn’t perfect.&lt;/p&gt;
&lt;p&gt;The workaround I used was that I just essentially created a little box that was
filled with a black color that would cut off a little piece off the end of the
date line on my images, and that ends up working ok.&lt;/p&gt;
&lt;p&gt;If you want to see the actual HTML/JSX I’m using to generate the image, I was
able to create a shareable link on the &lt;a href=&quot;https://og-playground.vercel.app/?share=nVXfT9swEP5XLE-TNqk0TWgHimAPbEOaNKRp8JiHOvUlMTh2ZDtAV_V_n52fdVu2QV_q3J3Pd9_3-bzBK0kBx_iCssdEIKTNmsPlZuPWCFGmK07WMVpmHJ6Xk9bq1l-ZgpVhUljfSvK6FL33iVFTWGsYzWbVsKcAlhfGmj-d7lhTsnrIlawF_SK5VDFKcMqtLcF9gFQUGruWnFEULqpn9A4WMIvoXtAvQlmtXWhkgwZnRShlInf2UyhROF1AOTgzKcw1KRm3LSb4ijPxcENWt2ttoLy2vi5wu03EZ7e4KMIBIWTbbkse62kS3rLf4Mxzd5Dd2-xEaLO8NXWWLW0umygowi5j9P8ZbQN-xhupwG7fTRu1aTs69wndoTTBjscBih7GO1n1WLWQ76M9cjkbLB3nCT5bvB8CHWoIdbXaPvvg_YrQ2LdPfkOf1KyVWYIVcGLYI3gBqTRGls4dTs92uXW_kqiciR-Q2WoT7FHf099jG3m-tvaheoR-SqsJiqRAN2SN5qbo2uoB34X8WIseuLaODtzDhgco94vtUT_0GEWEzqRqUFDSEAMf5gsK-ccXoSSpPb82PpSmre5kbm-o5-AdgOfuRh9D6SKwzbfCG1dvkGDLV0Om1-M_Su81MApS7Su0xf9qEEtk58hxfb9BtodXBCHCWS6-2znSjCTX5wkIP-QV8rt_JEqA1tOUy_xQeqzsjLZMtbpMcGFMpeMg8PYFrCQ56KBca-DZ9L6CPMHeFb7chNF5d3avON_2krLH6buYjSPgb5weDvdjs33EIvD01f7jCZaVE4bG8QY3LeDYPTwT3BaPY_veTDCFtM5xnBGuYYKhlPfsbl25d888NV82kWPjW5kCxbFRNWwn2JDURhTAuXySilO8_QM&quot;&gt;OG Playground&lt;/a&gt;
where you can see it.&lt;/p&gt;
&lt;p&gt;Once I had the image working, it was time to configure the plugin!&lt;/p&gt;
&lt;h2&gt;Configuring &lt;code class=&quot;language-text&quot;&gt;gatsby-plugin-satorare&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;The first thing you’re going to want to do is create a small JavaScript file
that acts as the “component” of the image. I say “component” because it’s not
so much a React component as much as it’s just something that uses JSX syntax
to define how the image is supposed to look.&lt;/p&gt;
&lt;p&gt;You’ll want this file to &lt;code class=&quot;language-text&quot;&gt;export default&lt;/code&gt; a &lt;code class=&quot;language-text&quot;&gt;function&lt;/code&gt; that takes an argument
that is a Gatsby &lt;code class=&quot;language-text&quot;&gt;Node&lt;/code&gt;. You can change the behavior of how the image is
rendered based on the type of node it is. In my case, all of my blog posts are
generated using the &lt;a href=&quot;https://www.gatsbyjs.com/plugins/gatsby-transformer-remark/&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;gatsby-transformer-remark&lt;/code&gt;&lt;/a&gt;
plugin, so they are all of type &lt;code class=&quot;language-text&quot;&gt;MarkdownRemark&lt;/code&gt;. I decided not to generate
images for all of the pages yet, so I’m only configuring the plugin to target
&lt;code class=&quot;language-text&quot;&gt;MarkdownRemark&lt;/code&gt; nodes. In the end, this is how my little component looked:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// src/components/social-image-card.js&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; postedDate &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;node&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;frontmatter&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;date&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toLocaleDateString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;undefined&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;month&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;long&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;day&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;numeric&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;year&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;numeric&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;div
      style&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;flex&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;flexDirection&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;column&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;1200px&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;630px&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;backgroundColor&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;black&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;border&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;solid 15px #e5e02d&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;borderRadius&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;25px&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;padding&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;3em 1.5em&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;fontFamily&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;BlinkMacSystemFont&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;h1 style&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;#e5e02d&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;fontSize&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;4em&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;node&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;frontmatter&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;title&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;h1&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;h2 style&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;#e5e02d&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;fontSize&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;3em&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;node&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;frontmatter&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;description&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;h2&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;div
        style&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;token literal-property property&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;flex&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token literal-property property&quot;&gt;borderTop&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;3em solid #e5e02d&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token literal-property property&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token literal-property property&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;75%&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;h2
          style&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token literal-property property&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;black&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token literal-property property&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;relative&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token literal-property property&quot;&gt;bottom&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;1.75em&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token literal-property property&quot;&gt;marginLeft&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;.5em&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token literal-property property&quot;&gt;fontSize&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;2em&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
          Posted on &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;postedDate&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;h2&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;div
          style&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token literal-property property&quot;&gt;borderTop&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;5em solid black&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token literal-property property&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;5em&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token literal-property property&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;5em&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token literal-property property&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;rotate(45deg)&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token literal-property property&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;absolute&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token literal-property property&quot;&gt;top&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;-40px&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token literal-property property&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;800px&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;div
        style&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;token literal-property property&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;flex&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token literal-property property&quot;&gt;margin&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;1em&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token literal-property property&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;absolute&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token literal-property property&quot;&gt;bottom&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token literal-property property&quot;&gt;right&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token literal-property property&quot;&gt;borderBottom&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;2px solid #e5e02d&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;h2
          style&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token literal-property property&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;#e5e02d&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token literal-property property&quot;&gt;alignItems&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;flex-end&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token literal-property property&quot;&gt;fontSize&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;2em&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
          jvarness&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;blog
        &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;h2&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;img
          src&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;https://jvarness.blog/images/myself.jpeg&quot;&lt;/span&gt;
          width&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;128&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
          height&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;128&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
          style&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token literal-property property&quot;&gt;borderRadius&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;50%&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token literal-property property&quot;&gt;margin&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;1em&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token literal-property property&quot;&gt;border&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;solid 5px #e5e02d&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As you can see here, it’s a little different from my example code in the OG
Playground, but the key differences are mainly that it’s templated using the
&lt;code class=&quot;language-text&quot;&gt;frontmatter&lt;/code&gt; contained within all my blog posts. Other than that, it’s pretty
much exactly what I put in the playground.&lt;/p&gt;
&lt;p&gt;One thing that is important to note here as well: you may notice that for the
whole component I’m using a font style &lt;code class=&quot;language-text&quot;&gt;fontFamily: &quot;BlinkMacSystemFont&quot;&lt;/code&gt;. In
order to get a custom font into the plugin to resolve correctly, you’ll need to
download the fonts you want to use. I was abel to find these fonts in &lt;a href=&quot;https://github.com/aliifam/BlinkMacSystemFont&quot;&gt;this
github repo&lt;/a&gt; and I was able to
get it in &lt;code class=&quot;language-text&quot;&gt;.otf&lt;/code&gt; format. I’m not sure if that matters or not, but the author
of the satorare plugin was using &lt;code class=&quot;language-text&quot;&gt;.otf&lt;/code&gt; in their example, so that’s what I did.&lt;/p&gt;
&lt;p&gt;Anyway, now that I’ve got the fonts I wanted to use &lt;em&gt;and&lt;/em&gt; I’ve got the
component created that I wanted to use, it’s time to modify my
&lt;code class=&quot;language-text&quot;&gt;gatsby-config.js&lt;/code&gt; with the correct configuration:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token literal-property property&quot;&gt;resolve&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;gatsby-plugin-satorare&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token literal-property property&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;__dirname&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;/src/components/social-image-card.js&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;fonts&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token literal-property property&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;BlinkMacSystemFont&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token literal-property property&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;__dirname&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;/content/assets/BlinkMacSystemFont.otf&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;target_nodes&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;MarkdownRemark&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now that this is configured, the plugin, at build time, will:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Load the font(s) you want to use&lt;/li&gt;
&lt;li&gt;Load up all the node types contained in the &lt;code class=&quot;language-text&quot;&gt;target_nodes&lt;/code&gt; array&lt;/li&gt;
&lt;li&gt;Call the &lt;code class=&quot;language-text&quot;&gt;social-image-card.js&lt;/code&gt; function for each of the nodes, which will
then create images for the pages.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Perfect. We’re almost done! Now that we have the images generating, now we need
to actually start using them.&lt;/p&gt;
&lt;h2&gt;Actually Using the Images&lt;/h2&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;gatsby-plugin-satorare&lt;/code&gt; will create new schema within the GraphQL store that
Gatsby uses to generate your site for each node type that you target. In this
case, it generated a &lt;code class=&quot;language-text&quot;&gt;markdownRemarkOgImage&lt;/code&gt; type in GraphQL that we can use
to reference the location of each image. We are able to do this using the IDs
of each blog post.&lt;/p&gt;
&lt;p&gt;For my blog posts, this was what the query used to look like:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; pageQuery &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; graphql&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
  query BlogPostBySlug($id: String!) {
    markdownRemark(id: { eq: $id }) {
      excerpt(pruneLength: 160)
      html
      frontmatter {
        title
        date(formatString: &quot;MMMM DD, YYYY&quot;)
        description
      }
      timeToRead
    }
  }
&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To be able to get the image data, I am now able to add a small snippet below
the &lt;code class=&quot;language-text&quot;&gt;markdownRemark&lt;/code&gt; query block:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; pageQuery &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; graphql&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
  query BlogPostBySlug($id: String!) {
    markdownRemark(id: { eq: $id }) {
      /* ... */
    }
    markdownRemarkOgImage(parent: { id: { eq: $id } }) {
      attributes {
        publicURL
      }
    }
  }
&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now when my blog posts render, the &lt;code class=&quot;language-text&quot;&gt;data&lt;/code&gt; prop will have the &lt;code class=&quot;language-text&quot;&gt;publicURL&lt;/code&gt; that
can be used for the image!&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;BlogPostTemplate&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; pageContext &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; publicURL &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;markdownRemarkOgImage&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;attributes
  &lt;span class=&quot;token comment&quot;&gt;// the rest of the code...&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I’m using the images mainly in a &lt;code class=&quot;language-text&quot;&gt;Helmet&lt;/code&gt; to be able
to set the appropriate meta tags for these to show up on social media. If you
are ever unsure of whether or not you’re using the right tags for this, I was
able to use &lt;a href=&quot;https://socialsharepreview.com/&quot;&gt;socialsharepreview&lt;/a&gt; to test them.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Well now my blog looks a little more professional! I’m pretty happy with the
way they turned out, and now hopefully social card links will look a little
nicer than they used to! Thanks for reading if you made it this far, and let me
know on DEV or LinkedIn if you tried this out at all and if it was helpful to
you!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Making Yourself a Garbage Collector]]></title><description><![CDATA[I Love Morning Walks, However… Over the course of the last few months, barring any cold weather, my wife and I
decided that we were going to…]]></description><link>https://jvarness.blog/making-yourself-a-garbage-collector/</link><guid isPermaLink="false">https://jvarness.blog/making-yourself-a-garbage-collector/</guid><pubDate>Wed, 10 Apr 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;I Love Morning Walks, However…&lt;/h1&gt;
&lt;p&gt;Over the course of the last few months, barring any cold weather, my wife and I
decided that we were going to start going on walks together with our daughter!
It’s been so nice in the morning being able to just go on a walk around our
community and see all the squirrels and rabbits running around, running into
the same neighbors that we’ve seen several times who’s name we don’t know
and their dogs who’s name we also don’t know, bumbling over crambly walking
paths, and of course, my most favorite part of all:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Walking down the sidewalk past all of the empty liqour shooters and coffee
cups, beer cans that had been shredded by lawn mowers, and lots of other
incredibly random pieces of trash, such as pieces of industrial electrical cable
and tupperware.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;What, who doesn’t love themselves some good ol’ fashion trash? It’s no secret
that people litter, and it’s not that I didn’t notice that there was &lt;em&gt;some&lt;/em&gt; trash before, but we didn’t always go on walks 3-5 times per week, and I never
noticed the &lt;em&gt;amount&lt;/em&gt; of trash around my neighborhood until we did. It was
just… Kinda gross. Really gross. Pretty yucky.&lt;/p&gt;
&lt;p&gt;Now, street sweepers would pick up trash sometimes, and they regularly come
around and clean up the streets, but they don’t get everything, and they
certainly don’t drive over the curb to pick up the trash on the sides of the
sidewalk. If you’re like me too, you’re probably not going to pick up any trash
unless it actually lands on your property. But… what if the property the
trash is on is technically owned by the city, but yet the city doesn’t send
anyone to pick the trash up? Well, you end up with what the three of us saw on
our morning walks.&lt;/p&gt;
&lt;p&gt;But then one day, at Target, I saw that they had these little plastic $5 trash
pickers, and I realized in that moment that I was going to become the one thing
I was always the most thankful for in so many programming languages:&lt;/p&gt;
&lt;h2&gt;Ma, I’m a Garbage Collector!&lt;/h2&gt;
&lt;p&gt;Picking up trash around your neighborhood can be really fun! All you gotta do
is get something you can pick up trash with. That could be a pair of heavy-duty
gloves (so that you don’t get poked or prodded), or it could be a grabber claw
thingy like I have (though I might recommend a heavier-duty one than the $5 one
from Target). For just $5, I’ve been able to relish in the newfound benefits
that garbage collecting around my neighborhood provides!&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 590px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/26b9687c9b2aa1532fc1fd7e4cab5841/b8471/garbage-collected.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAIAAABr+ngCAAAACXBIWXMAAC4jAAAuIwF4pT92AAADnklEQVR42gGTA2z8AB8hIhETFgQJDmVoZ1haWhYZGCkrKjc6O0xRVTQ7QxwlLhMbJBoeIhcZGmVmYRobGgYLDh0gIjAxLzY1MgBCREceIykCChRDRUZmaGgYHSI3NzY7PkBETFMsNT0cJC0UGiI1NzgmKSxqbGYUFxYLDxQiJyosLzEiKTAAcHN1JisyBA0XHSElYGFeIScrLS4uNDc6NT9GOUBFIiguJicpUE5KJioucXJqEBMUERYaLDEyKy8zIicvAIGFhl5kaQUPGQQKEU5QTjM3OSImJzhAR1NZXT1ESRgfJ1RRTDk5O0VGQ4mHehMXFhgdITk8PDAyMy8zNwCChoeqsbRZYWYFChImKSk1NzZVZXSFmKiSlJd9h49NY3pzgo9VW18xMS5UU0kYGxojJytBQkI6ODdXWFYAfoOFnaOlfoSGLDI3AAAAKykjfo+bmaq4epeQiKCljZ+wZnyQbHFzGRgWCQkIEBMVODc1TUtERkM+U1JQAGlnYoeLi3F4eiovMwAAAGBobaS1v3SGmXiIiIyml7rGzoybpU5TUyMjIgkLDBUYGEI+OE5HPllWUkZGRwBJQjpxcW1rcXQKDxUFCQ+NnamBkqSSoKujrbiFkZens7ihq7NFSUo2OT0fIyYVFxc+OzZKRT0/Pj4eIScATUlEQD48LC8yAwkRCw8VdHyDhJOgnqqzoq63lqWvr7i7tLy/aWZgYV5YVldWLjAxLCspPTs4ODs/Oz1BAFJSTywvMystMB0iKDM5PVxhZXuCiZajq5Slrpmpsq62uLi9uqiZgpuKdJ6OerWmjpqOe42EdI6Ie4SAdgCvpI92dXBZW15TVlpNUVNOVVt0eHx8foCHjpKVnqKZpKqws67Hs5S2o4evnoXDr5LQu5vMuJrFspbOvZ4AxLOY1MaoraWSgn10amhkWVlXT1FQVFZUZGdof4eMkZ2jp7Kz2c2r38qm1MGhxLKVyriZyrmbvq2UsJ+JAM28n9TDpeLSsdnJqsy6nrCgiJuNeYR5Z29mWXJqXnRybI+Pirm/nNjOptrHpce1l7imisSylMy8nse2mwDfz63RvqHBsJfKup/OvKDBr5O5p4yzoYemlX+qmH+nlXyqmYC1rY7Wy6XYyKbRwKC7qo68qo6/rJHDsZYA5daz2cinxLKWxLOX0L+gzbqcxbKWu6mOqpmCmYp2nY55sZ+Gw7KV1cOi2smn2silx7aWuKeKtaKJs6GJkBN2by1gtTkAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;A bag of trash I picked up from around my neighborhood, with the garbage
grabber I got leaning on top of it&quot;
        title=&quot;&quot;
        src=&quot;/static/26b9687c9b2aa1532fc1fd7e4cab5841/fcda8/garbage-collected.png&quot;
        srcset=&quot;/static/26b9687c9b2aa1532fc1fd7e4cab5841/12f09/garbage-collected.png 148w,
/static/26b9687c9b2aa1532fc1fd7e4cab5841/e4a3f/garbage-collected.png 295w,
/static/26b9687c9b2aa1532fc1fd7e4cab5841/fcda8/garbage-collected.png 590w,
/static/26b9687c9b2aa1532fc1fd7e4cab5841/efc66/garbage-collected.png 885w,
/static/26b9687c9b2aa1532fc1fd7e4cab5841/c83ae/garbage-collected.png 1180w,
/static/26b9687c9b2aa1532fc1fd7e4cab5841/b8471/garbage-collected.png 2016w&quot;
        sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Picking up trash around your community not only helps your neighborhood look
nicer and cleaner, but it’s also just a fun activity that literally anyone can
do, for little to no cost, that gets you out of the house. For someone like me,
who loves to spend their time writing code, making websites, and playing video
games, this is a great way for me to bump up my step counts.&lt;/p&gt;
&lt;p&gt;I’m probably not going to be picking up trash &lt;em&gt;every day&lt;/em&gt;, but I do think I’ll
enjoy doing this at least once per week for the foreseeable future. I’m really
hoping that the above bag of trash is not going to be the norm, and I honestly
think that picking up the trash that I did really did make a difference.&lt;/p&gt;
&lt;p&gt;Some of the trash that I had picked up was trash that had been sitting around
for at least a week, and I wasn’t really convinced that anyone was really going
to do anything about it. Besides, not everyone just walks around certain parts
of our neighborhood because they’re mostly empty plots of land. Still, it all
got there somewhere, and I know the wind didn’t shred those beer cans up.&lt;/p&gt;
&lt;p&gt;Anyway, it felt good to do something like this. I had never really done
anything like it before, and it felt a lot like cleaning around my house or
mowing my &lt;del&gt;beer cans&lt;/del&gt; grass or any other household chore: it took some time
to do it, but I felt a lot better about how everthing looked when it was all
said and done. Now when we go on our walks, I feel just a little less gross!&lt;/p&gt;
&lt;h2&gt;What Now?&lt;/h2&gt;
&lt;p&gt;Like I said, I’m going to try to do this once a week for a while. If you got
this far into the post, I’d encourage you to give this a shot, or find some
other way to help out around your neighborhood! Heck, some people even do live
streams of them picking up trash near where they live.&lt;/p&gt;
&lt;p&gt;This post was trash, but hopefully the next one will be something cool. Catch
all y’all on the next one.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Creating a Radio Using HTML Canvases]]></title><description><![CDATA[Hey everyone! It’s been a solid month since my last post, but I’m back again, and this time I want to focus on finishing up that crappy…]]></description><link>https://jvarness.blog/html5-acnh-radio-2/</link><guid isPermaLink="false">https://jvarness.blog/html5-acnh-radio-2/</guid><pubDate>Sun, 20 Dec 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Hey everyone! It’s been a solid month since my last post, but I’m back again, and this time I want to focus on finishing up that crappy little radio we made last time. For context, &lt;a href=&quot;https://ugly-kk-radio.vercel.app/&quot;&gt;here&lt;/a&gt; is what I left off with from &lt;a href=&quot;/html5-acnh-radio&quot;&gt;this post&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This little project started out as a submission for a programming competition, where I had to use 32 lines of code to make… Something, anything. But now that the competition is over, I can make this little project of mine whole with more code, specifically with CSS to draw a little radio on the screen, and some more JavaScript to make this project a little more robust than it is.&lt;/p&gt;
&lt;p&gt;But before we add play and pause functionality, we need to actually render something that resembles a radio. While it might not actually be a radio, I’m going to try to render something that looks like ACNH’s Tape Deck, because I like the way it looks.&lt;/p&gt;
&lt;h1&gt;Drawing a Radio&lt;/h1&gt;
&lt;p&gt;First, I need to draw a radio. Most people would likely just… Draw one in Paint, Gimp, or their other favorite image manipulation program. However, this is a coding blog, and drawing a .png file doesn’t require writing any code, so instead we’re going to use a HTML &lt;a href=&quot;https://www.w3schools.com/html/html5_canvas.asp&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;canvas&lt;/code&gt; element&lt;/a&gt;, which are really cool little elements you can use to draw things with using JavaScript.&lt;/p&gt;
&lt;p&gt;This was pretty tough for me to do because I didn’t fully know what methods were available to me in order to be able to draw the radio. I mostly needed to be able to draw shapes, but for the face of the radio I also wanted it to have some textures. I decided to go ahead and start with a box for the body of the radio. In order to do this I need a &lt;code class=&quot;language-text&quot;&gt;canvas&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;canvas&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;radio&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;500px&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;300px&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;canvas&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Easy. Now, I want to draw a box representing the body of the radio. In order to do that, I have to get the 2-dimensional context from the &lt;code class=&quot;language-text&quot;&gt;canvas&lt;/code&gt; and start drawing shapes:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; canvas &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;radio&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; ctx &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; canvas&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getContext&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;2d&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;beginPath&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fillStyle &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;#ddd&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fillRect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;25&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;450&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;250&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The code gets a little bit boring from here. It’s mostly repeating setting the &lt;code class=&quot;language-text&quot;&gt;fillStyle&lt;/code&gt; property and calling &lt;code class=&quot;language-text&quot;&gt;fillRect&lt;/code&gt; to draw most of the body. I also drew a couple of circles by calling the &lt;code class=&quot;language-text&quot;&gt;arc&lt;/code&gt; function to create a tape deck looking box, but the circle-drawing code is a little different. &lt;code class=&quot;language-text&quot;&gt;fillRect&lt;/code&gt; draws rectangles and fills them in with a pattern or solid color, whereas arcs can be drawn differently depending on whether or not you call &lt;code class=&quot;language-text&quot;&gt;fill&lt;/code&gt; or &lt;code class=&quot;language-text&quot;&gt;stroke&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;beginPath&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fillStyle &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;#aaa&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;arc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;128&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;210&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PI&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fill&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;beginPath&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fillStyle &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;#ddd&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;arc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;128&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;210&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PI&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fill&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;beginPath&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fillStyle &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;#aaa&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;arc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;170&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;210&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PI&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fill&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;beginPath&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fillStyle &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;#ddd&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;arc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;170&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;210&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PI&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fill&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This code will draw gray circles below much lighter-gray circles. Using &lt;code class=&quot;language-text&quot;&gt;fill&lt;/code&gt; here will create a circle filled in with a particular color based on what &lt;code class=&quot;language-text&quot;&gt;fillStyle&lt;/code&gt; is set to. &lt;code class=&quot;language-text&quot;&gt;stroke&lt;/code&gt;, however, has a different effect. Rather than just drawing a circle of the specified color, it draws a circle with a black outline.&lt;/p&gt;
&lt;p&gt;I wanted the stereo of the radio to have a textured look, but I didn’t want to repeat a ton of code to write little lines, so what I did is I created a tiny little image with the texture I wanted, and used the context’s &lt;code class=&quot;language-text&quot;&gt;createPattern&lt;/code&gt; function to create a pattern with that image:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; radioTexture &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
radioTexture&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;src &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;radio_texture.png&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
radioTexture&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;onload&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; radioPattern &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createPattern&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;radioTexture&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;repeat&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fillStyle &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; radioPattern&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;beginPath&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;arc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;350&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;175&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PI&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fill&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This made it really easy to create the texture I wanted without drawing it all using the canvas.&lt;/p&gt;
&lt;p&gt;After a little added CSS, I’m starting to like what I created. The radio is a little less ugly now, and it… Actually looks like a radio!&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 590px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/7a184fe73eaffc7aac4d75edf6be9928/1ddef/radio.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 68.24324324324324%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAA7DAAAOwwHHb6hkAAADS0lEQVR42nXRW0ybZRzH8acULaGFMQTHaQOJS7zdpdEL481mpl4tLk4qxAHluMIsMHUaNaBkbppMsoSoM/FmcOGIZhBO24IdtJSeoC10QI8ctJvZvBhTF83Xf18Z6oUXnzyH93l+z/P8X6VeHWLH0csaXbo98i17GkYosoywt3mUA29dw2j+XpvXba/7z96HVNUwmteG2VU3RmHDBLvrR8kXhQ2jFDWNU9oyQYV1kjJpCyyj7K6T75ZxdObtvf+mXp8gTWceI7/hOhVtdorbHezrmCW/ZZqiNofm8dYZ9p9yUdnlYp/NRUW7nUdqJsjY3r9D1UyRpnvDia76BrpjU1S+dI7yw2cof/lTytP9tBfPUnzoDCUHP6by0EeoY3YJENU/8DBDo47PkHHcgalqCFPNJCWN4zxbdY4yyzClUr8yUVo/TEndFfZbr/GU7QaHa89LOSYpaLhKjkVCZH86R6Nq3eQ1+en9pJevL40Q8vtxud24PZ4dHhEMBhkYHKS7p5uvLl7E5/USCXnoGXDJLT3o692oOqHqAxiaAzhDSVKbSeKJJMnkP+LxOJubm3R0dGAymcjMzMRgMHDklaPcXo/SNxqVwHn0jQGURajGMIYTYey+VRLRVRaXlgiHw5pQKMTGxgb9/f2yUJGVlYXRaNSkxx+8bePLqR+ldiH0LWFUk1DNUQzWCNMLMZaC88zOurQnpjmdTlZXVzGbzVpAbm4u2dnZ5OTkoHQZHHzuafrGE6jaCPpWuWmLUK3rGNrXJDDOUsDPwkKAlZUVlpeXpb9ALBajurpaC8zLy9MC08FK6Xjh+We4MLmJql9Db11HnRDKmsJgS0lgguC8j9k5Dz7/PF6fn1nXnDx7kUsDg+ildhkZegk08qjUMH3A+bM9fGG/I7X7Cf3JFKpNqJN3yeq8gysYYz2ySEBCQwte4ZMDvNxcDPBzaoMLn3/Gk0/sxWjIpGRPAV2dNu7ditE3tiZP/QW97S7qTaFsWxhO3eOyI8lcKM50IIEjmNwxI2O7P4o/cotxR4hvhq5yZcqHZ+U28+EY738nP8V6H33nFqpDqK4H6ETOu7+z673f/pfpnS0e+/APinuhsPtPTKfvy/yvZJ9+gOoUXX/7C5uXtOO6vWfvAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;A digital-looking screenshot of something that resembles a 90s tape deck.&quot;
        title=&quot;&quot;
        src=&quot;/static/7a184fe73eaffc7aac4d75edf6be9928/fcda8/radio.png&quot;
        srcset=&quot;/static/7a184fe73eaffc7aac4d75edf6be9928/12f09/radio.png 148w,
/static/7a184fe73eaffc7aac4d75edf6be9928/e4a3f/radio.png 295w,
/static/7a184fe73eaffc7aac4d75edf6be9928/fcda8/radio.png 590w,
/static/7a184fe73eaffc7aac4d75edf6be9928/1ddef/radio.png 635w&quot;
        sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;h1&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;I still have a lot more that I want to add to this, but this is a pretty good start for something looking a little bit better. To see the product as it is now, you can &lt;a href=&quot;https://less-ugly-kk.vercel.app/&quot;&gt;click here&lt;/a&gt;. I think at some point in 2021 we’ll start to add more functionality, and hopefully by… 2025 we’ll have a finished product!&lt;/p&gt;
&lt;p&gt;This is probably going to be the last blog post I make this year, so I just wanted to say that if you enjoyed any of my posts that I’ve written this year, first off thanks so much for reading, and let me know what your favorite one was and why on social media!&lt;/p&gt;
&lt;p&gt;Happy Holidays and a Happy New Year to you and your family and friends! I’ll see you all again in 2021!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Building an ACNH Radio using HTML5 Audio Tags]]></title><description><![CDATA[Cerner, the company I’m currently employed at, holds an annual hackathon called 2^5, where every day for 32 days, you can make 1 submission…]]></description><link>https://jvarness.blog/html5-acnh-radio/</link><guid isPermaLink="false">https://jvarness.blog/html5-acnh-radio/</guid><pubDate>Sat, 07 Nov 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://cerner.com&quot;&gt;Cerner&lt;/a&gt;, the company I’m currently employed at, holds an annual hackathon called 2^5, where every day for 32 days, you can make 1 submission of code that is 32 lines long or less. I’ve blogged about this previously on dev.to, and you can check out the post &lt;a href=&quot;https://dev.to/jvarness/32-lines-of-code-4bgc&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I’ve been a participant for 4 years, and it always surprises me how much folks are able to do using only 32 lines of code. This year was one of my favorite years to participate because I themed all of my submissions around Animal Crossing: New Horizons. Like millions of other Nintendo Switch gamers out there, ACNH became daily therapy as I caught bugs and fish, dug up fossils, and built an island full of really awesome villagers (the best overall being &lt;a href=&quot;https://nookipedia.com/wiki/Cherry&quot;&gt;Cherry&lt;/a&gt;, as I’m sure everyone who has ever had her as a villager would agree).&lt;/p&gt;
&lt;p&gt;What excited me even more was to find a &lt;a href=&quot;http://acnhapi.com/&quot;&gt;community-supported REST API&lt;/a&gt; for the new game that would allow you to query for &lt;em&gt;a lot&lt;/em&gt; of in-game items and get information about those items in the form of a JSON body, and almost every submission for 2^5 that I made &lt;a href=&quot;https://github.com/jvarness/cerner-2-to-the-5th/tree/master/2020&quot;&gt;this year&lt;/a&gt; revolved around this free API.&lt;/p&gt;
&lt;p&gt;There’s one submission that I made though that… Bothers me. A lot. I’ve thought about it non-stop since I submitted it, not for any reason other than the fact that it is visually one of the &lt;em&gt;ugliest&lt;/em&gt; things I’ve ever concocted. That submission is the &lt;a href=&quot;https://github.com/jvarness/cerner-2-to-the-5th/blob/master/2020/JS/kk/index.html&quot;&gt;radio that plays K.K. Slider songs&lt;/a&gt;. For brevity, I’ve deployed this file to Vercel &lt;a href=&quot;https://ugly-kk-radio.vercel.app/&quot;&gt;here&lt;/a&gt; so that you can see what it does.&lt;/p&gt;
&lt;p&gt;As you can see, this is really &lt;em&gt;really&lt;/em&gt; not visually appealing in any sense of the word. The JavaScript that was needed to make this work correctly made the file so large that there wasn’t really enough time leftover to make it pretty…&lt;/p&gt;
&lt;p&gt;I’m working on making it prettier right now, so for now, I’ll focus on what the &lt;code class=&quot;language-text&quot;&gt;audio&lt;/code&gt; tag in HTML5 can do for you, and how I used it to make a little mvp of a radio!&lt;/p&gt;
&lt;h2&gt;Retrieving Music&lt;/h2&gt;
&lt;p&gt;First thing we need to discuss is: how are we going to be retrieving the music we want to play? Well first I needed to go retrieve a song to play. The ACNH API has a &lt;a href=&quot;http://acnhapi.com/doc#tag/Songs&quot;&gt;Songs endpoint&lt;/a&gt; that makes this easy. Since I’m buildling a radio, I just want to go get random songs to play, so I’ll first start by generating a random integer in JavaScript between 1 and 95:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;floor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;94&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is one of those quirky things about JavaScript that I really dislike: unlike other modern languages that can actually generate a random integer, us JavaScript developers have to use a combination of &lt;code class=&quot;language-text&quot;&gt;Math.random&lt;/code&gt; (which generates a random decimal number between 0.0 and 1.0) and &lt;code class=&quot;language-text&quot;&gt;Math.floor&lt;/code&gt; (which will round a number down to it’s nearest whole number value, so numbers like 3.9, 3.7, and 3.0000001 all become 3). My intention here is to generate a random number between 1 and 95, because the ANCH API uses positive integers for the IDs, and currently the only way to get songs from the API is to use ID numbers within that range as query parameters:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; req &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;XMLHttpRequest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;GET&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;https://acnhapi.com/v1/songs/&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;floor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;94&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;onload&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setSong&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;response&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I’m not using NPM for this project, so just using &lt;code class=&quot;language-text&quot;&gt;XMLHttpRequest&lt;/code&gt; works for my needs. Now… What is that &lt;code class=&quot;language-text&quot;&gt;setSong&lt;/code&gt; and what does it do? Well, I use that to set some attributes on an &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTML/Element/audio&quot;&gt;HTML5 &lt;code class=&quot;language-text&quot;&gt;audio&lt;/code&gt; tag&lt;/a&gt;. Using this tag will help me answer the next conundrum:&lt;/p&gt;
&lt;h2&gt;Playing Music&lt;/h2&gt;
&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;audio&lt;/code&gt; tag, when provided with a music &lt;code class=&quot;language-text&quot;&gt;source&lt;/code&gt;, can play audio media straight from a browser once the browser has loaded the audio! So we can take our response from the API call, extract the URL of the MP3 from it, and begin to play it:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;audio&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;autoplay&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;source&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;audio/mpeg&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;Looks like your browser doesn&apos;t support audio tags :(
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;audio&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setSong&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;resp&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; json &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;resp&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;querySelector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;#text&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;textContent &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; json&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;name-USen&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;querySelector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;source&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setAttribute&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;src&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; json&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;music_uri&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;querySelector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;audio&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;load&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This code will set the &lt;code class=&quot;language-text&quot;&gt;src&lt;/code&gt; of the &lt;code class=&quot;language-text&quot;&gt;source&lt;/code&gt; tag, which will then allow the &lt;code class=&quot;language-text&quot;&gt;audio&lt;/code&gt; tag to start playing music, once it’s told to start playing. Before I go any further, I want to address how this code actually plays music, and why if you’re on a Chrome-based browser, the &lt;code class=&quot;language-text&quot;&gt;autoplay&lt;/code&gt; attribute likely isn’t causing the song to auto-play like you would expect:&lt;/p&gt;
&lt;p&gt;From the Mozilla docs I linked above, the &lt;code class=&quot;language-text&quot;&gt;audio&lt;/code&gt; tag has many attributes. The two main ones I want to focus on are &lt;code class=&quot;language-text&quot;&gt;autoplay&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;controls&lt;/code&gt;. Many browsers will honor &lt;code class=&quot;language-text&quot;&gt;autoplay&lt;/code&gt; if the &lt;code class=&quot;language-text&quot;&gt;controls&lt;/code&gt; attribute is included here, the reason being that &lt;code class=&quot;language-text&quot;&gt;controls&lt;/code&gt; asks the browser to supply music controls for the media. For this project, I don’t want to render the default controls, and I want it to still &lt;code class=&quot;language-text&quot;&gt;autoplay&lt;/code&gt; where available, which is why I left it in.&lt;/p&gt;
&lt;p&gt;However, Chrome refuses to &lt;code class=&quot;language-text&quot;&gt;autoplay&lt;/code&gt; any media without controls being present to play/pause said media. Because of this, I had to introduce something into the UI that would allow it to play the media based on a user-action, so I just added an &lt;code class=&quot;language-text&quot;&gt;onClick&lt;/code&gt; handler on the &lt;code class=&quot;language-text&quot;&gt;body&lt;/code&gt; tag, the entirety of which ends up looking like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;body&lt;/span&gt; &lt;span class=&quot;token special-attr&quot;&gt;&lt;span class=&quot;token attr-name&quot;&gt;onclick&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token value javascript language-javascript&quot;&gt;document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;querySelector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;audio&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;load&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token special-attr&quot;&gt;&lt;span class=&quot;token attr-name&quot;&gt;onload&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token value javascript language-javascript&quot;&gt;&lt;span class=&quot;token function&quot;&gt;loadNextSong&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;content&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;h2&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;h2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;h2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Click here to start playing music.&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;h2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;audio&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;autoplay&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;source&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;audio/mpeg&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;Looks like your browser doesn&apos;t support audio tags :(
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;audio&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;body&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now, when the page loads, the user is prompted to click somewhere in order to start playing music. Now, we’re building a radio, so when the first song we loaded stops, how do we load the next one?&lt;/p&gt;
&lt;h2&gt;Continuously Playing Music&lt;/h2&gt;
&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;audio&lt;/code&gt; tag comes with very convenient event handlers that we can take advantage of. The main one that we’ll be able to take advantage of for our radio is the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/ended_event&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;ended&lt;/code&gt;&lt;/a&gt; event. So far, the JavaScript we’ve written looks like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setSong&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;resp&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; json &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;resp&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;querySelector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;#text&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;textContent &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; json&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;name-USen&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;querySelector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;source&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setAttribute&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;src&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; json&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;music_uri&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;querySelector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;audio&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;load&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;loadNextSong&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;querySelector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;#text&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;textContent &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Loading...&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; req &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;XMLHttpRequest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;GET&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;https://acnhapi.com/v1/songs/&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;floor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;94&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;onload&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setSong&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;response&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We have functions for retrieving the next song, and loading it into our web page. However, this code will stop playing after the first randomly selected song. We can’t have it stop. What would K.K. Slider think of us if that happened?&lt;/p&gt;
&lt;p&gt;Luckily, we can just load the next song when the audio tag has ended the playing of media. We can do this by adding an event handler for the &lt;code class=&quot;language-text&quot;&gt;ended&lt;/code&gt; event:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;querySelector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;audio&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addEventListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;ended&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; loadNextSong&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;When the song stops playing, we’ll query up another song, set all the appropriate tags, and then &lt;code class=&quot;language-text&quot;&gt;document.querySelector(&apos;audio&apos;).load()&lt;/code&gt; will play the next song for us! Because we added &lt;code class=&quot;language-text&quot;&gt;autoplay&lt;/code&gt; to the audio tag, and the user had to click on the body of the page in order to start playing, songs will continue to play even in Chrome until the browser is closed!&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;This is not a bad start for an ACNH radio, but the internet deserves better! So far, I don’t have a way to turn the radio off once it’s on, and it… Really doesn’t look so much like a radio.&lt;/p&gt;
&lt;p&gt;Stay tuned for an upcoming post where I use some CSS magic to turn this blob of text on a screen into something we can all be proud of. Until then, I hope you liked learning a little bit about how you could use the &lt;code class=&quot;language-text&quot;&gt;audio&lt;/code&gt; tag! If you have any questions or feedback for me, links to my social media can be found on the footer of my website. Thanks for reading, and have a good one!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Adding serverless APIs to Gatsby projects in Vercel]]></title><description><![CDATA[Hey everyone! It’s been a solid two weeks since I’ve actually written a blog. I’ve been feeling really under the weather, so I’ve been…]]></description><link>https://jvarness.blog/adding-serverless-apis-to-gatsby-projects-in-vercel/</link><guid isPermaLink="false">https://jvarness.blog/adding-serverless-apis-to-gatsby-projects-in-vercel/</guid><pubDate>Sat, 31 Oct 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Hey everyone! It’s been a solid two weeks since I’ve actually written a blog. I’ve been feeling really under the weather, so I’ve been mostly taking the last few weeks easy (don’t worry, it wasn’t/isn’t COVID). That, and Pokemon Crown Tundra got released, so I’ve been playing a lot of that lately, but it feels nice to be back to writing some blogs!&lt;/p&gt;
&lt;p&gt;In the blog I wrote about &lt;a href=&quot;/how-this-site-was-made&quot;&gt;how I created my blog&lt;/a&gt;, I briefly mentioned that one of the reasons that I didn’t need to use Next.js for this site was because of the fact that it offered more functionality than I needed. All the pages on this site are built statically, and Next.js can do that too, but it also has great support for &lt;a href=&quot;https://nextjs.org/docs/api-routes/introduction&quot;&gt;dynamic routes and APIs&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I’m not convinced that this point that I’ll ever need dynamic routing built into this site since it’s using Gatsby. However, I might want to create APIs later for mailing lists, forms, etc. If I ever do need those APIs, Vercel actually makes it really easy to add APIs to any project.&lt;/p&gt;
&lt;p&gt;Originally this post was going to be about how easy making microservice APIs is using &lt;a href=&quot;https://github.com/vercel/micro&quot;&gt;micro&lt;/a&gt;, but then I discovered that micro was designed to be ran within a container, and that Vercel has better support for adding APIs to any Node project using it’s &lt;a href=&quot;https://vercel.com/docs/runtimes#official-runtimes/node-js/node-js-request-and-response-objects&quot;&gt;Serverless Helper Functions&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Adding an API&lt;/h2&gt;
&lt;p&gt;Adding serverless APIs to Vercel projects is dead simple. You can review the link above and find some instructions. What I’ve done on this site is I’ve deployed the example shown in the link to a route on my website at &lt;a href=&quot;/api/examples/hello-world&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;api/examples/hello-world&lt;/code&gt;&lt;/a&gt;. For posterity, the code just looks like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;module&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;exports&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;req&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; resp&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; name &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;World&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;query&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  resp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Hello &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;name&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is a fairly straight-forward function: it accepts two objects, one representing the &lt;code class=&quot;language-text&quot;&gt;req&lt;/code&gt;uest, which contains all the query parameters and any applicable bodies, and then an object we can use to send the &lt;code class=&quot;language-text&quot;&gt;resp&lt;/code&gt;onse with.&lt;/p&gt;
&lt;p&gt;I added this route by simply creating an &lt;code class=&quot;language-text&quot;&gt;api&lt;/code&gt; folder at the root of my project. Vercel will build out serverless API routes using the file structure defined within the &lt;code class=&quot;language-text&quot;&gt;api&lt;/code&gt; folder, and will serve any &lt;code class=&quot;language-text&quot;&gt;.js&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;.go&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;.py&lt;/code&gt;, or &lt;code class=&quot;language-text&quot;&gt;.rb&lt;/code&gt; files defined within as serverless lambda functions.&lt;/p&gt;
&lt;h2&gt;Consuming in Gatsby&lt;/h2&gt;
&lt;p&gt;I was really hoping to consume the API directly from this blog post, but I’m not using &lt;a href=&quot;https://github.com/mdx-js/mdx&quot;&gt;mdx&lt;/a&gt; for my posts quite yet, and injecting JavaScript in-line on a markdown file didn’t really seem like a very &lt;em&gt;safe&lt;/em&gt; thing to try and do, nor did I think it was feasible. SO, instead, I created an example page of how a Gatsby page might consume a serverless function.&lt;/p&gt;
&lt;p&gt;You can view the demo &lt;a href=&quot;/examples/api-example&quot;&gt;here&lt;/a&gt;, but I’ll talk more about the code here. You might consider opening the demo page up on another tab.&lt;/p&gt;
&lt;p&gt;In order to get the query parameters, Gatsby passes in &lt;a href=&quot;https://www.gatsbyjs.com/docs/location-data-from-props/&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;location&lt;/code&gt; data&lt;/a&gt; to each of it’s pages. We can use this, along with the &lt;a href=&quot;https://www.gatsbyjs.com/docs/recipes/querying-data/#querying-data-client-side-with-fetch&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;fetch&lt;/code&gt;&lt;/a&gt; API to grab the query params, can call our serverless function with the parameters:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;jsx&quot;&gt;&lt;pre class=&quot;language-jsx&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; React&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; useEffect&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; useState &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;react&apos;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Link &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;gatsby&quot;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; Layout &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;../../components/layout&quot;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;SEO&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;../../components/seo&quot;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; queryString &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;query-string&quot;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;location&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; search &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; location
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; name &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;World&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; queryString&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;search&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; greeting&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; setGreeting &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Loading...&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;useEffect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;/api/examples/hello-world?name=&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;name&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;resp&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; resp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;greet&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setGreeting&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;greet&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Layout&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;SEO&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Hello &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;name&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;section&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;className&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;hero is-white is-large&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;className&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;hero-body&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
          &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;h1&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;className&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;title&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;greeting&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;h1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;section&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;section&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
        If you stumbled upon this page not knowing what it was, go &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Link&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;/adding-serverless-apis-to-gatsby-projects-in-vercel&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt; here.&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Link&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;section&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Layout&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We’re able to use &lt;code class=&quot;language-text&quot;&gt;fetch&lt;/code&gt; to call an API using query parameters that were read from &lt;code class=&quot;language-text&quot;&gt;location&lt;/code&gt; data, and then render that data client-side once the server responds! Neato!&lt;/p&gt;
&lt;p&gt;The one thing you might notice when loading the page is that while the page rendering is pretty quick, there’s a bit of a delay in loading the actual information from the serverless function created by Vercel, hence our page says “Loading…” first before getting the actual greeting. I will say that this is one thing that Next.js does pretty well that Gatsby does not: all pages in Gatsby are static, whereas Next.js can actually create &lt;em&gt;lambdas&lt;/em&gt; of pages, so the loading and rendering of the data is handled server-side. If we were using Next.js, we could use it’s &lt;a href=&quot;https://nextjs.org/docs/basic-features/data-fetching#getserversideprops-server-side-rendering&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;getServerSideProps&lt;/code&gt;&lt;/a&gt; API to render everything server-side so that the client doesn’t have to load any data itself. No need for loading indicators.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Hopefully you’ve found some of this information useful! As always, links to my social media are located below if you want to ask questions about this post or if you want to suggest a future post. Thanks for reading!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Trying Out One-Line Dark Mode Tricks]]></title><description><![CDATA[I’ve read a few articles on the internet about how you can implement dark mode on your website in one line of CSS. Honestly, it’s a really…]]></description><link>https://jvarness.blog/trying-out-one-line-dark-mode-tricks/</link><guid isPermaLink="false">https://jvarness.blog/trying-out-one-line-dark-mode-tricks/</guid><pubDate>Tue, 13 Oct 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I’ve read a few articles on the internet about how you can implement dark mode on your website in one line of CSS. Honestly, it’s a really nifty trick. For reference, here are the articles I have seen:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://dev.to/dip15739/dark-mode-with-only-1-css-property-17fl&quot;&gt;Dark Mode with only 1 CSS PROPERTY&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://dev.to/akhilarjun/one-line-dark-mode-using-css-24li&quot;&gt;One line - Dark Mode using CSS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://dev.to/ekaterina_vu/dark-mode-with-one-line-of-code-4lkm&quot;&gt;Dark Mode With One Line Of Code&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It’s a neat trick, really it is. I’m a fan, and it works pretty well… For some websites. Since I now have a website, I thought to myself “self, why don’t you also include some kind of toggle for dark mode on your website using this trick!“.&lt;/p&gt;
&lt;p&gt;So I tried it… And uh… Well, let’s get into why I don’t really like the idea very much.&lt;/p&gt;
&lt;h2&gt;Trying with 1 CSS Style&lt;/h2&gt;
&lt;p&gt;Let’s just start with figuring out what this website looks like if we apply this filter style on my website in Chrome dev tools. Adding this CSS property on the &lt;code class=&quot;language-text&quot;&gt;&amp;lt;html&gt;&lt;/code&gt; element yields interesting results for the site:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;css&quot;&gt;&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token property&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;invert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;hue-rotate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;180deg&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;All the colors are inverted, but it turns out the yellow color I chose doesn’t look all that great when it’s inverted:&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 439px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/8f6d0135ca3708c17287af4772259998/e3b18/dark-mode-initial.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 68.91891891891892%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAB6ElEQVR42q2R30uaURjHj/J6o5LdiOiFoIgQgtAIcWMrb7a6jK6C/oquoqsKNtjl9ML7iF01xu4HW9PZ5iAwX00ztYwtB23W+/ojSF+/O+c4y/fNLrY68OE5z3Oe7/N+z3nJi9V5vHy+gPExgscTejx6QP6Zh+MEU0EBM6FRkKXFaawsz2EyIODZ5AiePjH/F9NTI5idcYCIu1+RTn3BQSGNwv7uFfv5FAoUHrX1gVxdT4N0Ol0w2m1FhaKwutJDAdqsp9Ov3+xnXF52QBqNOrTU6zJKRRE/vpc41ZMjnJ5W8bN6jMpRju9ZzzAtaTabuKZBaXFXnz5uIrb1BsWDFD6834CYTiARf4fX62v4HHvLXaq1PVQDW60LSFIN2UycOtxBbm8blcMsjQn6RklkxBgOyyJy2W36vkmcn//mmp6RvwMlScI1Ms7OasjnkpxyKYXjSh7FIvs53+jAOL3yHsrlDHdeq/2CLMsYnEFwj6vb7YJEIhFoCYfDt/BKlWs10WgUhC7cFZ1Ox6PZbAYRBAFaDAYDhzUy9Ho9j+ysv2fng/2sZrFY1A77X/L7/QiFQggGg/B6vfD5fByr1crzQCAAt9t9pVE5HDaQCRkejwd2ux0OhwNOpxNGoxE2mw0ulwsmk2nolf8AQbzY+Yms/jUAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;My website after inverting the colors and a 180-degree hue rotation&quot;
        title=&quot;&quot;
        src=&quot;/static/8f6d0135ca3708c17287af4772259998/e3b18/dark-mode-initial.png&quot;
        srcset=&quot;/static/8f6d0135ca3708c17287af4772259998/12f09/dark-mode-initial.png 148w,
/static/8f6d0135ca3708c17287af4772259998/e4a3f/dark-mode-initial.png 295w,
/static/8f6d0135ca3708c17287af4772259998/e3b18/dark-mode-initial.png 439w&quot;
        sizes=&quot;(max-width: 439px) 100vw, 439px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The whites turn black, the blacks turn white, and the yellow turns… Brown? Ew… Well, what if I just tried it without the &lt;code class=&quot;language-text&quot;&gt;hue-rotate&lt;/code&gt; style and just had &lt;code class=&quot;language-text&quot;&gt;filter: invert(1)&lt;/code&gt;? The result is a little bit better:&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 439px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/945668aa05f59a3d0a1b85a7d386155f/e3b18/blue-dark-mode.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 70.27027027027026%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABzElEQVR42q2PzUobURzFbz5WCZRKMDWRmObLZJFNyAMUsii48im66XO48BGELrJJUigV7aJWCsW1idJUkyrUT1SamYwzmZk7GUXI8d7bZpgRQQhe+HHu/fM/Z86QN2938e79CaYTTcy8bk3Eq2QLc/O7mM20QBYW21havsKL6W1MxZoT8XKmiXh6R5QitY+n+LTaw+e1HlbXJ4f7OcSyVAC3GMFm6ubmP7ZLn4bIsgLLsmGalgM1KS6vDPR6BhTFhCSbUFUqkCQTgwFle9TjGUP6fQW2bbNQS0CpJb60sSnh6zcJB4ca1r78xc+2is3vMlY+XODHloy7u6HjceME8qDh0IJhUPw5GjB07Hc0nJ3r2NtXcciC+bv7m6uK45MBdJ0KjydQlmVxMQyTVTahM+10r1kjBe09hRlV8W7/UtDa6ePoWGOtVRZ8DU0zWJF/vjGEh/EzGuFZDqlWq2g0GqjX6x5qtad56OEQv98PQsjzEQgE4PP5PPBZMBh0lvhsrO6dhz6x5244NuZyOVQqFZRKJRQKBeTzeRSLRUSjUWSzWZTLZSSTSY/H4bHASCSCWCyGdDqNRCKBeDyOVCqFcDgs5plMBqFQ6NFfvgcnO+5iwktfaAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;The yellows on the site turn blue instead&quot;
        title=&quot;&quot;
        src=&quot;/static/945668aa05f59a3d0a1b85a7d386155f/e3b18/blue-dark-mode.png&quot;
        srcset=&quot;/static/945668aa05f59a3d0a1b85a7d386155f/12f09/blue-dark-mode.png 148w,
/static/945668aa05f59a3d0a1b85a7d386155f/e4a3f/blue-dark-mode.png 295w,
/static/945668aa05f59a3d0a1b85a7d386155f/e3b18/blue-dark-mode.png 439w&quot;
        sizes=&quot;(max-width: 439px) 100vw, 439px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 439px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/00825432b79e64ac451f834ba755c477/e3b18/code-highlighting.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 61.48648648648649%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAA7DAAAOwwHHb6hkAAACSUlEQVR42m2Ty05iQRCGUeQmoFxcuDDD5RHcucCn4BlcQ1i4V4gLtiQmCkzCjg2bmYAGVOTcTx/POUZkhos4K1/jn65OnAyRxZ/qSlV93dVd7fF4PIhEItjc3EQgEIDf74fP50MwGPrnB4NBEc9ms8jn8zg8PITX6xV5VB8KhUT84OCAfI8o3N/fR61Ww/dmE43GNRr1a9TrdWGb5DfquLq6EjmXl5ci1mq1UK1WEYvFBFgANzY2sLW1hWwmg9fXCUx3CcWawXAXYM4vjNgMEpvjefwbrutAN0xuXRiGgfl0CvnhAfFEYhVIR0+lUlBVFbb9AsN0YFoOnmxeyFyohgvbeQZjDMzQYVsMJgeOx2N0u10k1gHT6TQ0XYNqKTBtDc6TCUWW+CYKh6jQFRmMbzCyXyE7E8g6g+PY6PV62NvbWwNMpaFzoGRouBkq6D8a6N70MRgM+FrBLVdPYvhxr+LnvYTbwT1kWUan01kP/MZbVngCYw4GQwv9kYVHWedFEoa85aHp4k61MOR3NrwbCKsoCtrtNpLJ5NdHyfBHocueTCZ4W0yFFosZ5vM5FrOp0Nt8hvf3d64/eFsu8fHxAUmSVoG0oDmjpy+VSri4uMD5eRnl8n/ifqVSwdnZGQqFAorFosg9PT3FyckJdnd3V4E02HRSGmJah8PhFUWjUWE/B5hyqe7TfhlsSqa26XLppDQG8XhciNoh7ezsCDDl0ETkcjkcHx+LWvoYX4D0laiQgCQCkCXA5wYUp+KjoyNomiYeZHt7ewX4F6/t/GjtdhXjAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;The code highlighting looks pretty good&quot;
        title=&quot;&quot;
        src=&quot;/static/00825432b79e64ac451f834ba755c477/e3b18/code-highlighting.png&quot;
        srcset=&quot;/static/00825432b79e64ac451f834ba755c477/12f09/code-highlighting.png 148w,
/static/00825432b79e64ac451f834ba755c477/e4a3f/code-highlighting.png 295w,
/static/00825432b79e64ac451f834ba755c477/e3b18/code-highlighting.png 439w&quot;
        sizes=&quot;(max-width: 439px) 100vw, 439px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;This looks a little bit better, even some of the posts don’t look too bad: the code snippets and inline highlighting don’t look all that bad. However, there are other subtle elements of the site that don’t really look right. The footer, for example, has a really poor contrast ratio between the links I have there and the now white background:&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 429px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/4ad97793a76b507a7d138206e2f99f68/3d026/footer-with-blue.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 43.24324324324324%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABcklEQVR42oWRT0vDQBDF+029ePDiBxIEQRAUPIkXEVoPkhZNS5qkiUltbJumNlqTNNls/rTw3F1JsC3i4TGZ3ZnfvNk00jRFJUJSPMlLWMMIqh7gUVoiDAlsO4LvJ7i5XUDVArxYEaZujKKgouc3o1GBKE2RJAQHhxZaD58MFuLq+gPOG8HJ6TtGToKjYwcXlwvc3fs4O/dQln8Ad12WRQbX9eA4E3jeDJOpyxxydyOMxx4bThEw57uwLSAhpFaWZbAsE7rWh65r6PcVDG0bpqGyIa/snrIestVTA6skz3MROYw3lGWJ9XqDzYZpXTLXBdbsm5/z5+F1vIe75aqBQRBAURRIkoRer8tiGwNVAfUM5HMd5kBDV35GvrCReiYsQ0ez2UK73Uan04Esy0JxHAuwWJknq9WqjmEYIiWJWCvxJyAzA/RrLs4SVsPvuaqeKIrqtQWwsl2JryNW4DmD0LgaQPdq91be/Uv7ogL8f90P8BtXaqLfTy8JgQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;The footer with just invert(1)&quot;
        title=&quot;&quot;
        src=&quot;/static/4ad97793a76b507a7d138206e2f99f68/3d026/footer-with-blue.png&quot;
        srcset=&quot;/static/4ad97793a76b507a7d138206e2f99f68/12f09/footer-with-blue.png 148w,
/static/4ad97793a76b507a7d138206e2f99f68/e4a3f/footer-with-blue.png 295w,
/static/4ad97793a76b507a7d138206e2f99f68/3d026/footer-with-blue.png 429w&quot;
        sizes=&quot;(max-width: 429px) 100vw, 429px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;My fear here is that users who have colorblindness might not be able to easily see some of these links. The icons look pretty good inverted though, so what I can do is make the links the same color as the icons, and that’ll solve that problem pretty easily, because they’ll turn the same blue as the icons:&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 463px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/626a7a6bd0f8b03c917187ea0acc8d66/71ce0/blue-links.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 37.16216216216216%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAAA7DAAAOwwHHb6hkAAABR0lEQVR42n2RS0+DQBSF++tduHHhHzBxa+LeuNDWanWh8REpMDyGAi0waZEyA7RNjpdpK9WFi5N7h5z7zT1DT0qJvcpSomkU+ncC7x8LjB4FXt/mYE4Ozr/QH2S4uk5gWjksO0dTKz1zyOj9BW42CkfHPm5uMwwf5rgfLTAYzvH8kuPsfIqT0xCjJ4GLyyk263+AZVn+qIWuVhUcZmM8NmBZBnzfheva1H+ips2qaj8jf0E1sKoqAqwobk1qaKAmSSRJjDRNMZu1NabzDEKInbfZeSv9TNsLCKiUQhzHMAwDtm3DcRgcN6BawOdLejsfjKVwPUm+DKY5JplajFm0dQSbFYiiQkM1sN3C8zwEQaABnhdQX4AHOUX1qRfweIEwSgjSXuqQj9N3jslkijBcIsuWUOogcheh3kXf/vEultT1MG7n7yJ/A9zUC5GiUgpiAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Links are as blue as the icons on the footer&quot;
        title=&quot;&quot;
        src=&quot;/static/626a7a6bd0f8b03c917187ea0acc8d66/71ce0/blue-links.png&quot;
        srcset=&quot;/static/626a7a6bd0f8b03c917187ea0acc8d66/12f09/blue-links.png 148w,
/static/626a7a6bd0f8b03c917187ea0acc8d66/e4a3f/blue-links.png 295w,
/static/626a7a6bd0f8b03c917187ea0acc8d66/71ce0/blue-links.png 463w&quot;
        sizes=&quot;(max-width: 463px) 100vw, 463px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
        decoding=&quot;async&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;So this isn’t too bad still… But I’m not sure I really like the blue color still. I picked that yellow because I like it. I want it to stay that way. Plus, this is just a style: I still need to figure out a way to turn it off and on again, which will require some JavaScript on my part.&lt;/p&gt;
&lt;p&gt;I’ll eventually get a dark mode added to my website, but I don’t think I’ll be using this method for it. I think for other websites that have simpler color schemes this might be a great technique to use! But for my website, it’s just not working the way I want it to.&lt;/p&gt;
&lt;h2&gt;Other Examples&lt;/h2&gt;
&lt;p&gt;Other websites have great examples of how their dark mode is implemented. One notable one is Dan Abramov’s site &lt;a href=&quot;https://overreacted.io/&quot;&gt;overreacted.io&lt;/a&gt;. Dan is the creator of React, and this blog was created using Gatsby! You can check out the source code &lt;a href=&quot;https://github.com/gaearon/overreacted.io&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Dan’s implementation is very elegant: the base color scheme for all the text and content just looks visually appealing regardless of whether or not the background is light or dark. The background becomes a different color based on classes added to the &lt;code class=&quot;language-text&quot;&gt;body&lt;/code&gt; of the page. Dan also has some code in here that will persist the selected theme between sessions so that the next time the site is visited it’s using the same theme.&lt;/p&gt;
&lt;p&gt;The Gatsby community seems to agree that this is a pretty good implementation! Someone from the community decided to create a plugin that implements much of the code that Dan uses to persist the theme state and trigger updates to the theme. Source code for that plugin can be found &lt;a href=&quot;https://github.com/insin/gatsby-plugin-dark-mode&quot;&gt;here&lt;/a&gt;. For anyone looking to implement similar themes or triggers, this is a good starting point!&lt;/p&gt;
&lt;h2&gt;Wrapping Up&lt;/h2&gt;
&lt;p&gt;So what does this teach us about dark mode? You can certainly use a CSS style like &lt;code class=&quot;language-text&quot;&gt;filter&lt;/code&gt; to invert all of the colors on your website to achieve the desired effect, but as the color scheme I’m using can prove, it can be a little difficult to implement it using &lt;code class=&quot;language-text&quot;&gt;filter&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;In a later blog post, if I’m ever going to be able to figure out how to make this work for my site, I’ll discuss how I overcame all these different challenges, and how I was able to actually implement it.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[How I made jvarness.blog]]></title><description><![CDATA[A colleague of mine reached out to me and asked if I could spend a little bit of time blogging about how I created this blog. I told that…]]></description><link>https://jvarness.blog/how-this-site-was-made/</link><guid isPermaLink="false">https://jvarness.blog/how-this-site-was-made/</guid><pubDate>Wed, 07 Oct 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;A colleague of mine reached out to me and asked if I could spend a little bit of time blogging about how I created this blog. I told that colleague I would soon, so hopefully they’ll enjoy this.&lt;/p&gt;
&lt;p&gt;Aside from being asked by a colleague: I want to talk about what my needs &lt;em&gt;currently&lt;/em&gt; are for the blog, the technologies I’m using to create the blog, and why I chose those technologies over competitors.&lt;/p&gt;
&lt;h2&gt;&lt;del&gt;Bear&lt;/del&gt; Bare Necessities&lt;/h2&gt;
&lt;p&gt;First things first: this is a blog. It’s a website, not an app, and I knew I didn’t need or want to maintain any kind of app. That helped narrow down my tech search. I wanted this to just be a website that I could post my thoughts and ideas and projects to.&lt;/p&gt;
&lt;p&gt;There were things I could have done that would have made the site much more complicated to setup initially, but I could have added more features over time: I could have created some kind of Ruby on Rails application and served my content via a CMS such as &lt;a href=&quot;https://strapi.io/&quot;&gt;Strapi&lt;/a&gt;, but there were two major concerns that I had about that:&lt;/p&gt;
&lt;p&gt;First thing is that I would have needed to setup and deploy both the website in Rails, as well as a Strapi instance somewhere like &lt;a href=&quot;https://www.digitalocean.com/&quot;&gt;Digital Ocean&lt;/a&gt; or on &lt;a href=&quot;https://www.heroku.com/&quot;&gt;Heroku&lt;/a&gt;, but for something like a blog there are cheaper options.&lt;/p&gt;
&lt;p&gt;The second concern I would have had about that is performance: Rails screams, but only if you have the hardware an infrastructure to help it scale. I didn’t want to worry too much about performance with this, because in the end it’s &lt;em&gt;just a blog&lt;/em&gt;, and you could end up paying big with that kind of server side rendering architecture… Or really any kind of rendering for that matter.&lt;/p&gt;
&lt;p&gt;I knew that I could achieve better performance through static rendering and generation than I could if I hosted my content on a CMS and loaded that content in for each page hit, and because I know how to write JavaScript (and I like to write JavaScript code), it became pretty clear what I wanted to do: &lt;a href=&quot;https://jamstack.org/&quot;&gt;JAMStack&lt;/a&gt; it!&lt;/p&gt;
&lt;h2&gt;JAMStack&lt;/h2&gt;
&lt;p&gt;In the world of JAMStack, there are many technologies and companies that make it extremely simple to make a website. In fact, on the JAMStack site, there are a ton of options &lt;a href=&quot;https://jamstack.org/generators/&quot;&gt;listed here&lt;/a&gt; that can help you achieve what you’re wanting to do. I’m not going to talk about all of the options that you have, but I will talk about a few that I did consider:&lt;/p&gt;
&lt;h3&gt;Next.js&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://nextjs.org/&quot;&gt;Next.js&lt;/a&gt; is a React framework for building websites, created by &lt;a href=&quot;https://vercel.com/&quot;&gt;Vercel&lt;/a&gt; (formerly Zeit), with the aim of being extremely flexible: site pages can be generated statically, they can render dynamically using microservice APIs, it’s easy to add your own microservices into the same code base, and code-splitting is built-in, meaning that your JavaScript isn’t bundled into one big blob, but rather just the JavaScript that each individual page needs.&lt;/p&gt;
&lt;p&gt;For pages that are dynamically rendered, Next.js creates a lambda function, which is a huge plus for anyone who wants to create dynamically rendered pages: lambda functions are a great way to keep the costs of deploying a website down, and it doesn’t require a server to be constantly running.&lt;/p&gt;
&lt;p&gt;I’m a huge fan of using Next.js to build applications and websites. I would recommend it to a lot of people. However, I didn’t really feel as if I needed &lt;em&gt;all&lt;/em&gt; of the power that Next.js had to offer: I don’t have a need to create any microservices, and if I did I can always create and deploy those very easily. If I did feel as if I needed them though, Next.js would be what I would reach for.&lt;/p&gt;
&lt;p&gt;One other thing I don’t find particularly convenient about Next.js is the ability to create posts using Markdown: Kendall Strautman made a blog that you can find &lt;a href=&quot;https://dev.to/tinacms/creating-a-markdown-blog-with-next-js-52hk&quot;&gt;here&lt;/a&gt; on how to setup a Markdown blog using Next.js. I spent a good long while trying to get this to work with &lt;a href=&quot;https://www.netlifycms.org/&quot;&gt;NetlifyCMS&lt;/a&gt;, but Next.js just isn’t elegant for this because I believe at it’s core it’s trying to solve a completely different use-case: quickly rendering pages through the use of microservice architectures. But like I said, I don’t really need those, I just want to write Markdown and get a site working.&lt;/p&gt;
&lt;h3&gt;Nuxt.js&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://nuxtjs.org/&quot;&gt;Nuxt&lt;/a&gt; is another JavaScript framework that looks to solve many of the same use-cases as Next, but instead of using React it uses Vue.&lt;/p&gt;
&lt;p&gt;I don’t really have more experience with Nuxt than I do with Next, but of the experience that I do have, I can tell you that Nuxt’s plugin system is pretty elegant. With Next, there tends to be a lot of webpack configuration you have to go through in order to get things exactly how you want them if you’re deviating from use-cases that Next tries to solve. In my opinion, Nuxt has a lot more intuitive configuration and plugin setup, and there are so many nice conventions in Nuxt that make organizing the source code very easy.&lt;/p&gt;
&lt;p&gt;For more complex websites, Nuxt is a great option for those who want more configurability in their site, or for those who just love Vue more than they love React. Nuxt really was a close second for this site.&lt;/p&gt;
&lt;h3&gt;Gatsby&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://www.gatsbyjs.com/&quot;&gt;Gatsby&lt;/a&gt; is considered to be the defacto static site generator for React developers by many in the React/JAMStack community. It’s primary goal is to utilize APIs to create static pages. It heavily utilizes GraphQL and plugins curated by the Gatsby community to query data sources and build a site. It’s also very easy to learn if you have a good understanding of React. In fact, much of the groundwork for this website was laid using the tutorial on Gatsby’s website, found &lt;a href=&quot;https://www.gatsbyjs.com/tutorial/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The main difference between Nuxt/Next and Gatsby to me is that Gatsby makes it extremely easy to source information from files within a repository in order to build the content, whereas Nuxt/Next make it easy to create small services that can be used to dynamically render pages. To me, this was the simplest and easiest way to create a blog: I wrote posts in Markdown, and Gatsby turns it into a website!&lt;/p&gt;
&lt;p&gt;The one caveat about Gatsby, that I think I’m willing to compromise on at the moment, has to deal with build times. Next and Nuxt are both best tailored to load content from REST APIs, which means that your build times are only as long as it takes to build each lambda or static page that your site requires. You sacrifice a small portion of load times to have extremely fast builds.&lt;/p&gt;
&lt;p&gt;As of the publishing of this post, there are only a total of 4 blog posts, and as such, Gatsby’s build times are extremely quick. However, with my current implementation, Gatsby won’t be able to scale as I continue to add more and more posts. My builds will start to take longer because Gatsby will have to build &lt;em&gt;every single post&lt;/em&gt; as a new page.&lt;/p&gt;
&lt;p&gt;However, loading times for statically rendered sites are significantly faster than those backed by services. In this case, I’m willing to sacrifice slower builds to be able to host the same content and have that content be really fast to load.&lt;/p&gt;
&lt;h2&gt;Hosting&lt;/h2&gt;
&lt;p&gt;There are about as many options for hosting as there are for actually generating your site. I already mentioned Digital Ocean and Heroku, but those fit different use-cases than what I was really needing. I didn’t want to have to manage an OS, or hardware resources, or whether or not I wanted my site to be scalable… I just wanted to deploy a website.&lt;/p&gt;
&lt;p&gt;There are a few platforms I’m aware of that make this extremely easy to do. I’ll discuss two of them that I didn’t use, and what I ultimately decided to utilize.&lt;/p&gt;
&lt;h3&gt;Surge&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://surge.sh/&quot;&gt;Surge&lt;/a&gt; is a platform you can use to deploy static sites quickly and easily. It offers a CLI that can be easily installed via NPM, and the free tier is extremely generous in terms of being able build as many projects into Surge as you want. It’s really easy to use.&lt;/p&gt;
&lt;p&gt;However, Surge is almost too simple: your website has to be built first in order to deploy it. The project has to be in a pre-built state before being published to the Surge network. This means that if you want to automate deployments when you push to a repo, you’ll need to setup some kind of continuous integration service to take care of getting the CLI and publishing for you. If you’re interested in Surge but you want automated deployments, there should be a guide in the docs on how to set it up with an old favorite of mine, &lt;a href=&quot;https://travis-ci.org/&quot;&gt;Travis&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Sadly, I did not choose Surge for my deployments and hosting.&lt;/p&gt;
&lt;h3&gt;Netlify&lt;/h3&gt;
&lt;p&gt;Oh boy… I’m sure I’m going to get some flak for this… I’ll admit it: I’ve actually never tried using &lt;a href=&quot;https://www.netlify.com/&quot;&gt;Netlify&lt;/a&gt;. For those of you reading this who love Gatsby, you must think I’m crazy. You might be right.&lt;/p&gt;
&lt;p&gt;Netlify is a big favorite amongst many in the JAMStack community, and it’s not hard to understand why: Netlify deploys sites to a super fast CDN, and is capable of deploying static pages, as well as lambdas. It’s a really great choice for anyone who is creating a website with Nuxt, Next, Gatsby… Really, any static site generator.&lt;/p&gt;
&lt;p&gt;Netlify also has an easy-to-integrate CMS aptly named &lt;a href=&quot;https://www.netlifycms.org/&quot;&gt;Netlify CMS&lt;/a&gt;. The way that Netlify CMS works is that the data is actually all hosted in GitLab or GitHub, and Netlify CMS will load posts from those sources. Then, when a post is edited or added, those updates will be pushed to the repository from Netlify CMS on your behalf, and can be stored as JSON, Markdown, whatever is supported.&lt;/p&gt;
&lt;p&gt;This is Gatsby’s strong suit: since the data that Gatsby uses to generate all of the pages is held within the repo itself, it’s possible to easily add Netlify CMS to any Gatsby site.&lt;/p&gt;
&lt;p&gt;Netlify, Netlify CMS, and Gatsby, would all be extremely attractive options if you wanted to create a website for practically no money down, and you wanted multiple people to be able to contribute to it, or if you wanted people who were not engineers to be able to contribute without having to understand Markdown or code. Couple that with things that developers care about, like Git integration and built-in site generation and deployments, and you have a match made in heaven.&lt;/p&gt;
&lt;p&gt;… Or at least for other people. Not necessarily for me. There’s another platform I’ve been using for quite some time now that I just can’t stop using.&lt;/p&gt;
&lt;h3&gt;Vercel/Zeit&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://vercel.com/&quot;&gt;Vercel&lt;/a&gt; (Zeit) is a company that you may or may not have heard about: I don’t think they get nearly the amount of praise that Netlify does or the kind of attention that Netlify typically does, but they are just as good as Netlify for building and deploying sites. The company itself owns a lot of really neat &lt;a href=&quot;https://vercel.com/oss&quot;&gt;open-source software&lt;/a&gt; that you may already be using, such as the Hyper terminal emulator, and they’re also the minds behind Next.js, Mongoose… My main point is that they do a lot of really neat stuff.&lt;/p&gt;
&lt;p&gt;There are so many great things about Vercel that make it an excellent platform for developers: a free pricing tier that allows you to deploy all kinds of projects is just the start. Actually, fun fact about Vercel: as of the writing of this article, ALL personal accounts are FREE, meaning you don’t have to pay anything to deploy your personal projects. Accounts only become paid if they are team accounts, where you want multiple contributors to join your project.&lt;/p&gt;
&lt;p&gt;Next are the different features: full integration with GitLab, GitHub, and Bitbucket, easy to use integrations to other sites through their integrations marketplace, but probably my favorite feature of all is the CLI.&lt;/p&gt;
&lt;p&gt;With the &lt;a href=&quot;https://vercel.com/docs/cli&quot;&gt;Vercel CLI&lt;/a&gt;, it’s possible to take advantage of all the power Vercel has to offer right at your fingertips. You can buy a domain name, manage DNS records for your domains, deploy a node project straight to the Vercel platform (regardless of whether or not it’s stored in a Git repository), manage deployments… Literally anything you would normally want to manage through a web client, you can do on the command line. You never have to leave your development environment to manage your projects in production. Like Surge and Netlify, Vercel will also deploy your site with every push, can can create vanity URLs on it’s platform for every Git branch you create.&lt;/p&gt;
&lt;p&gt;For me, having used Vercel for many years, this wasn’t a difficult decision to make.&lt;/p&gt;
&lt;h2&gt;That’s About All Folks&lt;/h2&gt;
&lt;p&gt;And that’s all she wrote! These are the decisions that lead me to develop my website the way you’re currently experiencing it. Hopefully these insights and thoughts that I’ve expressed have perhaps inspired you to consider creating your own blog, or experimenting with creating any kind of static website. Like I said before: there’s not much risk involved with using these platforms. It’s very easy, and almost always free, to create and experiment with different technologies and ways of creating websites. If you have any questions, please reach out to me on social media! You can find links below. I’d be happy to answer your questions or hear your feedback. Thanks for reading!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[My Gripes about C-Style for-loops]]></title><description><![CDATA[One of the most useful (and often one of the most fundamental) concepts when learning to code is looping.
Loops are all around us, in…]]></description><link>https://jvarness.blog/my-gripes-about-c-style-for-loops/</link><guid isPermaLink="false">https://jvarness.blog/my-gripes-about-c-style-for-loops/</guid><pubDate>Fri, 25 Sep 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;One of the most useful (and often one of the most fundamental) concepts when learning to code is looping.
Loops are all around us, in virtually every language we know, and even if your language of choice doesn’t
include primitive loops, there is likely a way to achieve executing the same block of code a fixed number
of times, or by implementing some kind of basic means of iterating.&lt;/p&gt;
&lt;p&gt;The first programming language that I ever wrote code in was Python, but the first programming language I
really got a firm grasp on, and that I still use to this day, is Java.&lt;/p&gt;
&lt;p&gt;Over Java’s history, it’s evolved immensely: JDK 11 has introduced modules, which is another way of organizing
a codebase, JDK 8 introduced lambda functions (a feature which existed in many other langauges including
C# and JavaScript for some time), and JDK 5 was when the enhanced for-loop was introduced.&lt;/p&gt;
&lt;p&gt;JDK 5’s last update was over a decade ago, but regardless of how old it is, I can’t help but notice that
sometimes people are continuing to use C-Style for-loops, and not only that, but I can find very heavy
usage of C-Style loops in a lot of code bases in other languages as well, such as C#. I want to write
this blog post as a caution to those who are continuing to use this loop, and provide reasons as to why
whenever I see C-Style loops in a code review, I’ll &lt;em&gt;almost always&lt;/em&gt; ask someone to refactor it.&lt;/p&gt;
&lt;h2&gt;Stability&lt;/h2&gt;
&lt;p&gt;My first big gripe about C-Style for-loops is that they are extremely prone to bugs. For every line of
code you write within a C-Style for-loop, there could be an error in almost every line, and there can
be potentially a number of bugs that are present before you even start talking about what’s in the loop.
Let’s look at a simple example, printing numbers in an array:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; nums &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; nums&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token class-name&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;out&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;nums&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;There’s technically nothing wrong with this code. We created an array, looped over each of the elements in
that array, and printed each number out to the console. However, this loop is prone to all kinds of bugs.
This code works without defects or error IF and ONLY IF:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;i&lt;/code&gt; is not mutated within the loop, and nothing is stopping it from being manipulated either temporarily or&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;permanently&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;i&lt;/code&gt; is always incremented by 1 after each execution of the loop&lt;/li&gt;
&lt;li&gt;The &lt;code class=&quot;language-text&quot;&gt;&amp;lt;&lt;/code&gt; condition doesn’t change&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;i&lt;/code&gt;’s initial value does not change&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If any of these things changes for any reason, we run the risk of encountering &lt;code class=&quot;language-text&quot;&gt;ArrayIndexOutOfBoundsException&lt;/code&gt;s,
not looping over each element, or skipping elements within the array. For having the simple task of iterating over
5 numbers, this seems like a lot of risk to impose at runtime.&lt;/p&gt;
&lt;p&gt;We can mitigate all of these issues by using alternative methods to looping over this structure. Since JDK 5,
developers have been able to take advantage of enhanced for-loops, also referred to as for-each loops (yet again
another construct that’s always been available in C#).&lt;/p&gt;
&lt;p&gt;Using an enhanced for-loop, the code now looks like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; nums &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; num &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; nums&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token class-name&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;out&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;num&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This code will iterate over the array, and on each invocation of the loop it will assign the a value to the
variable &lt;code class=&quot;language-text&quot;&gt;num&lt;/code&gt;, then we can use that number without having to access the array! This addresses all of the
concerns we had about C-Style for-loops in terms of stability.&lt;/p&gt;
&lt;p&gt;Enhanced for-loops can be used with any data structure that implements Java’s &lt;a href=&quot;https://docs.oracle.com/javase/8/docs/api/java/lang/Iterable.html&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Iterable&lt;/code&gt;&lt;/a&gt;
interface, and because the &lt;a href=&quot;https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Collection&lt;/code&gt;&lt;/a&gt; interface
extends &lt;code class=&quot;language-text&quot;&gt;Iterable&lt;/code&gt;, we can use it for every &lt;code class=&quot;language-text&quot;&gt;List&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;Set&lt;/code&gt; in our code.&lt;/p&gt;
&lt;p&gt;Speaking of &lt;code class=&quot;language-text&quot;&gt;Collection&lt;/code&gt;s, let’s discuss my next big gripe:&lt;/p&gt;
&lt;h2&gt;Time Complexity&lt;/h2&gt;
&lt;p&gt;Let’s start this discussion with another example. I have a &lt;code class=&quot;language-text&quot;&gt;List&lt;/code&gt; that I’m iterating over and I want to
print each element in the &lt;code class=&quot;language-text&quot;&gt;List&lt;/code&gt;, and let’s start with a C-Style loop:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;token generics&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Integer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; nums &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ArrayList&lt;/span&gt;&lt;span class=&quot;token generics&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
nums&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
nums&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
nums&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
nums&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
nums&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; nums&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token class-name&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;out&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;nums&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Again, same as before: nothing too fancy about this code, and it works fine. Now, let’s switch from using &lt;code class=&quot;language-text&quot;&gt;ArrayList&lt;/code&gt; to &lt;code class=&quot;language-text&quot;&gt;LinkedList&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;token generics&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Integer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; nums &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;LinkedList&lt;/span&gt;&lt;span class=&quot;token generics&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
nums&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
nums&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
nums&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
nums&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
nums&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; nums&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token class-name&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;out&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;nums&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is the exact same output, and at face value the only real difference is the fact that we’re using a different implementation
of the &lt;code class=&quot;language-text&quot;&gt;List&lt;/code&gt; interface. However, that’s an &lt;em&gt;extremely crucial&lt;/em&gt; difference in this situation.&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;ArrayList&lt;/code&gt; is what it sounds like: it’s an implementation of the &lt;code class=&quot;language-text&quot;&gt;List&lt;/code&gt; interface that uses an array as it’s underlying structure.
This means that extracting data out of the list can happen in constant time.&lt;/p&gt;
&lt;p&gt;However, &lt;code class=&quot;language-text&quot;&gt;LinkedList&lt;/code&gt; is a linked data structure. With an &lt;code class=&quot;language-text&quot;&gt;ArrayList&lt;/code&gt;, the compromise for performance happens when adding elements to
the list: the array has to “grow” by creating a new array with a larger size than the current underlying array, and moving all the
elements to that new reference, and then garbage collection will take care of the rest. &lt;code class=&quot;language-text&quot;&gt;LinkedList&lt;/code&gt;s are really efficient
during the population of the list because the structure can be created in such a way that growing the list can happen in constant
time. However, this comes at a cost of accessing the data by index: each &lt;code class=&quot;language-text&quot;&gt;.get&lt;/code&gt; call will yield an n^2 time complexity, n being the
index you’re trying to access.&lt;/p&gt;
&lt;p&gt;Just by switching from &lt;code class=&quot;language-text&quot;&gt;ArrayList&lt;/code&gt; to &lt;code class=&quot;language-text&quot;&gt;LinkedList&lt;/code&gt;, we exponentially increased the time complexity of this code. However, enhanced
for-loops can help mitigate this issue:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;token generics&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Integer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; nums &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;LinkedList&lt;/span&gt;&lt;span class=&quot;token generics&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
nums&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
nums&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
nums&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
nums&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
nums&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Integer&lt;/span&gt; num &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; nums&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token class-name&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;out&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;num&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;But why is this more beneficial in terms of time complexity? Remember: &lt;code class=&quot;language-text&quot;&gt;List&lt;/code&gt;s are &lt;code class=&quot;language-text&quot;&gt;Collection&lt;/code&gt;s which are &lt;code class=&quot;language-text&quot;&gt;Iterable&lt;/code&gt;. Each implementation of
a &lt;code class=&quot;language-text&quot;&gt;List&lt;/code&gt; comes with a built-in &lt;a href=&quot;https://docs.oracle.com/javase/8/docs/api/java/util/List.html#iterator--&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Iterator&lt;/code&gt;&lt;/a&gt; which can be used
to efficiently iterate over the list. Normally, &lt;code class=&quot;language-text&quot;&gt;Iterator&lt;/code&gt;s are designed to be as efficient as possible. &lt;code class=&quot;language-text&quot;&gt;Iterator&lt;/code&gt;s can be scoped to
the class implementing them to allow them to have scope to the internal members of the data structure, which allows them to do things like
access links within a &lt;code class=&quot;language-text&quot;&gt;LinkedList&lt;/code&gt; directly so that the next link can be fetched without having to loop over them like most &lt;code class=&quot;language-text&quot;&gt;.get&lt;/code&gt; operations
would normally do.&lt;/p&gt;
&lt;p&gt;Why wouldn’t we just use &lt;code class=&quot;language-text&quot;&gt;ArrayList&lt;/code&gt; everywhere if this was the case though? You can control whether or not your API uses &lt;code class=&quot;language-text&quot;&gt;ArrayList&lt;/code&gt;, sure, but
that won’t stop other engineers from using some other kind of implementation in theirs, so guard yourself against these types of caveats
by using the right loops.&lt;/p&gt;
&lt;h2&gt;Alternatives to Enhanced for-loops&lt;/h2&gt;
&lt;p&gt;What are some other ways we could achieve the same kind of results without using for-loops? In JDK 8, Java was introduced to lambdas and
&lt;code class=&quot;language-text&quot;&gt;Stream&lt;/code&gt;s, which aim to vastly improve our code by allowing us to manipulate structures by passing function references to &lt;code class=&quot;language-text&quot;&gt;Streams&lt;/code&gt; to
perform work. We can write code like this to do the same kind of work:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;nums&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forEach&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;num&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;out&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;num&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is a lambda that just calls &lt;code class=&quot;language-text&quot;&gt;System.out.println&lt;/code&gt; on a variable called &lt;code class=&quot;language-text&quot;&gt;num&lt;/code&gt; that gets initialized to a new element in the &lt;code class=&quot;language-text&quot;&gt;List&lt;/code&gt;
on each invocation. We can also simplify this code even further with some syntactic sugar:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;nums&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forEach&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;out&lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Apart from enhanced for-loops and lambdas, the only other thing I could recommend is using the actual &lt;code class=&quot;language-text&quot;&gt;Iterator&lt;/code&gt; class in conjunction with
a &lt;code class=&quot;language-text&quot;&gt;while&lt;/code&gt; loop:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;Iterator&lt;/span&gt;&lt;span class=&quot;token generics&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Integer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; numIterator &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; nums&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;iterator&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;numIterator&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;hasNext&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token class-name&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;out&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;numIterator&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This has less issues than a C-Style for-loop does, but it can still pose issues if &lt;code class=&quot;language-text&quot;&gt;.next&lt;/code&gt; is called more than once within
the &lt;code class=&quot;language-text&quot;&gt;while&lt;/code&gt; block. Nevertheless, it’s just as efficient as an enhanced for-loop. If I remember correctly… I think
Java bytecode compiles down in such a way that a while-loop with an &lt;code class=&quot;language-text&quot;&gt;Iterator&lt;/code&gt; and an enhanced for-loop are equivalent.&lt;/p&gt;
&lt;h2&gt;Cases for C-Style&lt;/h2&gt;
&lt;p&gt;So now that I’ve gone on and on about how you shouldn’t use a C-style for-loop, let’s talk about when you should actually
use one.&lt;/p&gt;
&lt;p&gt;There might be some cases when you simply cannot use an enhanced for-loop, or where the other methods I outlined don’t make
logical sense. Maybe you code has to execute a finite number of times, and it’s not based on a collection or data structure
of any kind. Maybe it’s based on some count, or a requirement stating that something needs to be done X-times.&lt;/p&gt;
&lt;p&gt;I spoke about time complexity in this post, but truth be told enhanced for-loops are not the single most efficient loop
there is. In cases involving the need to iterate over data, yes, enhanced for-loops are your best bet, but they come
at a slight performance cost of needing to keep track of the state of the &lt;code class=&quot;language-text&quot;&gt;Iterator&lt;/code&gt;, as well as the additional calls
to get the info out of the &lt;code class=&quot;language-text&quot;&gt;Iterator&lt;/code&gt;. For applications where performance, both in terms of memory and time
consumption, it might not be wise to utilize &lt;code class=&quot;language-text&quot;&gt;Iterator&lt;/code&gt;s or enhanced for-loops.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Thanks for letting me air out my grievances about one of our oldest language constructs! If you enjoyed this post,
I’d love to hear your feedback on Twitter or Dev! Be sure to check out my blog for other posts like this!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Why I love Bulma]]></title><description><![CDATA[I’ve never been good at styling things. This website might be some evidence of that! 😁 But styling a website
isn’t just about picking color…]]></description><link>https://jvarness.blog/why-i-love-bulma/</link><guid isPermaLink="false">https://jvarness.blog/why-i-love-bulma/</guid><pubDate>Wed, 23 Sep 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I’ve never been good at styling things. This website might be some evidence of that! 😁 But styling a website
isn’t just about picking color schemes: fonts, spacing, icons, etc… There’s a lot to consider when all I
really want to do is create a few pages that look decent.&lt;/p&gt;
&lt;p&gt;I’ve tried &lt;a href=&quot;https://getbootstrap.com/&quot;&gt;Bootstrap&lt;/a&gt; before, which has been a staple of the internet for many
years, and &lt;a href=&quot;https://tailwindcss.com/&quot;&gt;Tailwind&lt;/a&gt; has gained significant traction over the last few years,
but my go-to library for my CSS needs has been &lt;a href=&quot;https://bulma.io/&quot;&gt;Bulma&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I think I discovered Bulma through Twitter. I think someone tweeted about it, and the more I looked
into it the more interested I became. Hopefully just talking about some of the things I like about
Bulma might spark more interest in it!&lt;/p&gt;
&lt;h2&gt;Components/Elements&lt;/h2&gt;
&lt;p&gt;Bulma has many components built into it that are very easy to setup, and are well documented! One big
selling point that Bulma pushes is that it’s all in one CSS file. In the big world of programming, you
can always take a bunch of different CSS files, and minify them into one file. The selling point here
is mainly to emphasize that Bulma comes with &lt;em&gt;no javascript bundle&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;90% of the time, this isn’t a problem: all of the components Bulma has to offer work without any javascript.
There is &lt;em&gt;one&lt;/em&gt; exception to this rule though, which you can find in the documentation &lt;a href=&quot;https://bulma.io/documentation/components/navbar/#navbar-menu&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;TL;DR: &lt;code class=&quot;language-text&quot;&gt;navbar&lt;/code&gt; elements require some javascript to get them to appropriately collapse in mobile. The example
they have on their site has a pretty extensive javascript that’ll handle multiple navbars. I’m usually
only creating one as part of my layout, so I just slap some IDs on the elements I care about:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;jsx&quot;&gt;&lt;pre class=&quot;language-jsx&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;a&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;burger&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;onClick&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;toggleStyles&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;role&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;button&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; 
  &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;navbar-burger&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;data-target&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;navMenu&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;aria-label&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;menu&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;aria-expanded&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;false&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;span&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;aria-hidden&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;true&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;span&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;span&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;aria-hidden&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;true&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;span&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;span&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;aria-hidden&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;true&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;span&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;navbar-menu&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;navbarmenu&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
  &amp;lt;!-- other elements here --&gt;
&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Toggling whether or not to make the menu visible becomes trivial using a few selectors and an &lt;code class=&quot;language-text&quot;&gt;onClick&lt;/code&gt; event
bound to that burger:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;/*
* Added this to toggle the is-active class. See:
* 
* https://bulma.io/documentation/components/navbar/#navbar-menu
* https://github.com/jgthms/bulma/issues/856
*/&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;toggleStyles&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;querySelector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;#burger&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;classList&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toggle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;is-active&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;querySelector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;#navbarmenu&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;classList&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toggle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;is-active&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;One other quick tip: Microsoft Edge has issues with how Bulma has implemented navbars, but this can be fixed
with CSS. Multiple work-arounds can be found &lt;a href=&quot;https://github.com/jgthms/bulma/issues/2503&quot;&gt;here&lt;/a&gt; depending on
your use-case.&lt;/p&gt;
&lt;h2&gt;Customization&lt;/h2&gt;
&lt;p&gt;Bulma is very variable-oriented. Pretty much everything that has a default in Bulma can be customized. Colors,
responsive breakpoints, fonts, you name it, anything can be customized!&lt;/p&gt;
&lt;p&gt;This comes in handy when you have a site that has a very particular color scheme. It’s possible to customize
the colors and sizes of a lot of elements just by setting a variable.&lt;/p&gt;
&lt;p&gt;You can check out the full list of variables &lt;a href=&quot;https://bulma.io/documentation/customize/variables/&quot;&gt;here&lt;/a&gt;. I’m
one of those individuals who tries not to put CSS in too many places. As a stylistic preference, I’m not normally
a fan of sytles within HTML or JSX. I’ll normally write one Sass file, and overwrite Bulma’s variables as needed,
and that way it gets applied throughout the whole site:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;scss&quot;&gt;&lt;pre class=&quot;language-scss&quot;&gt;&lt;code class=&quot;language-scss&quot;&gt;&lt;span class=&quot;token property&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$primary&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; #c01045
&lt;span class=&quot;token keyword&quot;&gt;@import&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;~bulma/scss/bulma.scss&apos;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That color I chose was as close as I could get to spelling out “colors” in hexidecimal format, but in this
example, we’re changing the &lt;code class=&quot;language-text&quot;&gt;$primary&lt;/code&gt; color of Bulma. Bulma has a variety of colors that are available by
default, and they can be used for a variety of purposes, including denoting success or indicating something that
the user should give some attention to. Other colors like &lt;code class=&quot;language-text&quot;&gt;$danger&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;$warning&lt;/code&gt; can be customized to help
apply the same color across multiple components.&lt;/p&gt;
&lt;h2&gt;Responsiveness&lt;/h2&gt;
&lt;p&gt;Bulma is responsive right out of the box. There are a number of breakpoints that Bulma comes packaged with,
and they can be used in conjunction with styles to ensure that elements are displaying only when they’re supposed
to be.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://bulma.io/documentation/helpers/visibility-helpers/#hide&quot;&gt;Here&lt;/a&gt; is where an entire list of classes can
be found that can help with displaying/hiding elements based on sceensize. For example, the following
element displays differently based on screensize:&lt;/p&gt;
&lt;div class=&quot;is-hidden-touch has-background-black has-text-white&quot;&gt;You&apos;re on a larger device!&lt;/div&gt;
&lt;div class=&quot;is-hidden-desktop has-background-black has-text-white&quot;&gt;You&apos;re on a smaller device!&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;is-hidden-touch has-background-black has-text-white&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;You&apos;re on a larger device!&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;is-hidden-desktop has-background-black has-text-white&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;You&apos;re on a smaller device!&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Depending on your use-case, this could be a very nifty trick up your Bulma sleeve.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I hope that I’ve sparked a little bit of interest in Bulma with this post. If you’ve got any feedback for me, I’d
love to hear back from you! Links to my social media platforms can be found at the bottom of this page!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Press Start]]></title><description><![CDATA[As I start writing this, it feels so surreal and exciting. To be honest, I wasn’t sure if I would
ever start a blog. I don’t have any…]]></description><link>https://jvarness.blog/press-start/</link><guid isPermaLink="false">https://jvarness.blog/press-start/</guid><pubDate>Mon, 21 Sep 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;As I start writing this, it feels so surreal and exciting. To be honest, I wasn’t sure if I would
ever start a blog. I don’t have any logistics figured out for this: &lt;em&gt;when&lt;/em&gt; should I post, or
&lt;em&gt;how often&lt;/em&gt; should I post, or really anything like that. I just know I have ideas for things
to write about, and I’m going to use this site to write about them!&lt;/p&gt;
&lt;p&gt;So who am I? I’m Jake, and I’ve spent a number of years working as a software engineer/developer. I went
to Eastern Washington University and I graduated with a Bachelor’s in Computer Science. During school, I
worked as a software developer for a company called &lt;a href=&quot;https://www.service-link.ca/&quot;&gt;Service-Link&lt;/a&gt; where
I developed a number of enhancements to their build scripts, as well as to their Android and Windows
applications. From there, I went on to work for &lt;a href=&quot;http://cerner.com/&quot;&gt;Cerner&lt;/a&gt;, and that’s where I’ve been
ever since! I started as a software engineer, and I’ve spent my career developing software used by pharmacists,
nurses, and physicians across the globe to manage patient care.&lt;/p&gt;
&lt;p&gt;For nearly the last decade, I’ve been living and breathing enterprise software development, and I’ve had my
hands on all kinds of programming languages and technologies: Java, C#, JavaScript, C++, SQL, Ruby…
I’ve done quite a bit. There are also some other languages I’ve learned for fun, like Dart and Kotlin.&lt;/p&gt;
&lt;p&gt;But enough about my LinkedIn profile, what’s this blog about?&lt;/p&gt;
&lt;p&gt;Well…&lt;/p&gt;
&lt;p&gt;To be honest I don’t have much of a plan, just ideas. I’m really just hoping that I can put this
out there, promote it, talk about different types of software engineering topics that I find interesting,
maybe meet some of you through Twitter or DEV.to along the way. This is just me… Taking a deep dive
into the world of blogging and seeing what I’ll come back up to the surface with.&lt;/p&gt;
&lt;p&gt;In the past, I’ve written blogs on &lt;a href=&quot;https://dev.to/&quot;&gt;DEV.to&lt;/a&gt;, which has an excellent following an community
for all developers. While I’ve really enjoyed blogging on there in the past… Well, you can kind of tell
that I haven’t really written much. It’s been over a year since my last post and uh… Well… It was a
joke…&lt;/p&gt;
&lt;p&gt;No, not in like a self-deprecating type of way, it was literally a &lt;a href=&quot;https://dev.to/jvarness/why-was-0110-afraid-of-0111-56nc&quot;&gt;corny joke post&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Part of my hope in creating this site is that I’ll be more motivated to keep updating it, and more
motivated to post new content and new stories and whatnot. The thought of sharing knowledge on a platform
that I’m &lt;em&gt;solely responsible for&lt;/em&gt; places that extra sense of responsibility to keep creating content.&lt;/p&gt;
&lt;p&gt;Overall, I’m really excited to start blogging, and I hope to make more posts very soon! If you
have any questions you want to ask me, you can find links to my social media profiles on the footer of
the site that you can use to contact me! Thanks for reading! Have a good one.&lt;/p&gt;</content:encoded></item></channel></rss>