<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Devin Schulz</title>
    <link>https://devinschulz.com/</link>
    <description>Writing from Devin Schulz.</description>
    <language>en</language>
    <atom:link href="https://devinschulz.com/index.xml" rel="self" type="application/rss+xml" />
    <lastBuildDate>Thu, 29 Oct 2026 00:00:00 &#43;0000</lastBuildDate>
    
    <item>
      <title>Building a Chat Interface That Doesn&#39;t Fight Your Scroll Position</title>
      <link>https://devinschulz.com/blog/building-a-chat-interface-that-doesnt-fight-your-scroll-position/</link>
      <guid>https://devinschulz.com/blog/building-a-chat-interface-that-doesnt-fight-your-scroll-position/</guid>
      <pubDate>Thu, 29 Oct 2026 00:00:00 &#43;0000</pubDate>
      <description>&lt;p&gt;A chat interface that scrolls to the bottom on every update makes it difficult to read anything except the latest response. Scroll up to check an earlier message and the next chunk pulls you straight back down.&lt;/p&gt;
&lt;p&gt;I mentioned this problem in &lt;a href=&#34;https://devinschulz.com/blog/the-hardest-part-of-frontend-development-isnt-writing-code/&#34;&gt;my post about the decisions around frontend code&lt;/a&gt;. It&amp;rsquo;s a good example of a small interaction that needs more thought than its first implementation suggests.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;d start by separating two things: whether a response is streaming, and whether someone wants to follow it. Scrolling up should pause the following without stopping the response. Loading earlier messages should preserve the message they&amp;rsquo;re reading, even if new text is still arriving below it.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Reflecting on Twelve Years of Remote Work</title>
      <link>https://devinschulz.com/blog/reflecting-on-twelve-years-of-remote-work/</link>
      <guid>https://devinschulz.com/blog/reflecting-on-twelve-years-of-remote-work/</guid>
      <pubDate>Wed, 21 Oct 2026 00:00:00 &#43;0000</pubDate>
      <description>&lt;p&gt;Nearly twelve years into remote work, I still value the flexibility and the time I&amp;rsquo;ve saved commuting. I also still have to work at knowing when to stop for the day.&lt;/p&gt;
&lt;p&gt;I started working remotely when I joined InVision in December 2014. The entire company was distributed, and working with people I&amp;rsquo;d mostly see through a screen took some getting used to.&lt;/p&gt;
&lt;p&gt;When people found out I worked from home, the questions were usually pretty similar. How do you stay motivated? Don&amp;rsquo;t you get lonely? Do you actually get dressed in the morning?&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>The Hardest Part of Frontend Development Isn&#39;t Writing Code</title>
      <link>https://devinschulz.com/blog/the-hardest-part-of-frontend-development-isnt-writing-code/</link>
      <guid>https://devinschulz.com/blog/the-hardest-part-of-frontend-development-isnt-writing-code/</guid>
      <pubDate>Sun, 18 Oct 2026 00:00:00 &#43;0000</pubDate>
      <description>&lt;p&gt;After more than a decade of frontend development, I find deciding how an interface should behave harder than writing the code. A failed request, a slow connection, or an unexpected interaction can expose decisions that were never made during design.&lt;/p&gt;
&lt;p&gt;When I first started building websites, most of my time went into getting things to work. I&amp;rsquo;d take a design, write some HTML and CSS, add JavaScript, and eventually get something that looked and behaved the way I wanted.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Using React Component Variants to Compose CSS Classes</title>
      <link>https://devinschulz.com/blog/using-react-component-variants-to-compose-css-classes/</link>
      <guid>https://devinschulz.com/blog/using-react-component-variants-to-compose-css-classes/</guid>
      <pubDate>Sun, 20 Feb 2022 00:00:00 &#43;0000</pubDate>
      <description>&lt;p&gt;When it comes to styling variations of a component, we often concat classes
together in a non-idiomatic way. In this post, I will outline one pattern I&amp;rsquo;ve
been using to apply classes to an element. It has stayed readable, typesafe, and flexible enough to keep adding variants easily.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s get started.&lt;/p&gt;
&lt;p&gt;We will create a generic button component with various styles depending on size
and type. How we apply these classes is not button-specific and could be used to
style inputs, dropdowns, or any other component you can think of.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>My Definition of a First-Class Pull Request</title>
      <link>https://devinschulz.com/blog/my-definition-of-a-first-class-pull-request/</link>
      <guid>https://devinschulz.com/blog/my-definition-of-a-first-class-pull-request/</guid>
      <pubDate>Tue, 25 Aug 2020 00:00:00 &#43;0000</pubDate>
      <description>&lt;p&gt;Over the years, I have worked on a few projects where I was the sole developer.
Being a sole developer has its challenges since not everyone reviewing your pull
requests (or merge requests for the GitLab folks) has an understanding of the
repository like I do. Because of this, I like to give a bit more context to
every pull request I create, so reviewers know what to expect when reviewing
code.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Handling an Event Callback Once</title>
      <link>https://devinschulz.com/blog/handling-an-event-callback-once/</link>
      <guid>https://devinschulz.com/blog/handling-an-event-callback-once/</guid>
      <pubDate>Sun, 12 Jul 2020 00:00:00 &#43;0000</pubDate>
      <description>&lt;p&gt;An interesting tidbit I stumbled upon recently is the ability to remove an event listener once it&amp;rsquo;s called.&lt;/p&gt;
&lt;p&gt;In the past, I would have added an event listener to an element and then removed
it within the callback function. It would have looked something like this:&lt;/p&gt;
&lt;figure class=&#34;code-block not-prose my-8 min-w-0 overflow-hidden rounded-xl border border-white/10 bg-[#171a20] text-[13px] leading-[1.7] text-[#eee] [&amp;_pre]:m-0 [&amp;_pre]:max-w-full [&amp;_pre]:overflow-x-auto [&amp;_pre]:bg-transparent [&amp;_pre]:p-5 desktop:[&amp;_pre]:p-7 [&amp;_pre:focus-visible]:outline-2 [&amp;_pre:focus-visible]:outline-offset-[-3px] [&amp;_pre:focus-visible]:outline-white [&amp;_pre:focus-visible]:ring-0 forced-colors:[&amp;_pre:focus-visible]:outline-[Highlight] [&amp;_code]:font-mono [&amp;_code]:text-[inherit]&#34; data-controller=&#34;code&#34; data-action=&#34;keydown-&gt;code#scroll turbo:before-cache@document-&gt;code#clear&#34;&gt;
  &lt;figcaption class=&#34;flex min-h-11 flex-wrap items-center justify-between gap-x-4 border-b border-white/10 px-5 text-xs text-[#b8c2d1] desktop:px-7&#34;&gt;
    &lt;span id=&#34;code-label-0&#34; class=&#34;font-mono&#34;&gt;JavaScript&lt;/span&gt;
    &lt;div class=&#34;ml-auto flex items-center gap-3&#34;&gt;
      &lt;span class=&#34;font-mono&#34; aria-hidden=&#34;true&#34;&gt;.js&lt;/span&gt;
      &lt;button hidden type=&#34;button&#34; data-code-target=&#34;button&#34; data-action=&#34;code#copy&#34; aria-label=&#34;Copy JavaScript code&#34; class=&#34;group/copy inline-flex min-h-11 min-w-18 items-center justify-center rounded-md font-sans text-xs text-[#eee] disabled:cursor-wait disabled:opacity-60 focus-visible:outline-2 focus-visible:outline-offset-[-3px] focus-visible:outline-white focus-visible:ring-0 forced-colors:focus-visible:outline-[Highlight] [[hidden]]:hidden&#34;&gt;
        &lt;span class=&#34;pointer-events-none inline-flex min-h-7 min-w-18 shrink-0 items-center justify-center gap-1.5 rounded-md border border-white/15 px-1.5 whitespace-nowrap group-hover/copy:bg-white/10&#34;&gt;
          &lt;svg data-code-target=&#34;copyIcon&#34; class=&#34;shrink-0&#34; width=&#34;12&#34; height=&#34;12&#34; viewBox=&#34;0 0 16 16&#34; fill=&#34;none&#34; stroke=&#34;currentColor&#34; stroke-width=&#34;1.25&#34; aria-hidden=&#34;true&#34;&gt;&lt;rect x=&#34;5&#34; y=&#34;5&#34; width=&#34;9&#34; height=&#34;9&#34; rx=&#34;1.5&#34;/&gt;&lt;path d=&#34;M3 11H2.5A1.5 1.5 0 0 1 1 9.5v-7A1.5 1.5 0 0 1 2.5 1h7A1.5 1.5 0 0 1 11 2.5V3&#34;/&gt;&lt;/svg&gt;
          &lt;svg hidden data-code-target=&#34;checkIcon&#34; class=&#34;shrink-0 [[hidden]]:hidden&#34; width=&#34;12&#34; height=&#34;12&#34; viewBox=&#34;0 0 16 16&#34; fill=&#34;none&#34; stroke=&#34;currentColor&#34; stroke-width=&#34;1.5&#34; aria-hidden=&#34;true&#34;&gt;&lt;path d=&#34;m3 8 3 3 7-7&#34;/&gt;&lt;/svg&gt;
          &lt;span data-code-target=&#34;label&#34; class=&#34;shrink-0 whitespace-nowrap&#34;&gt;Copy&lt;/span&gt;
        &lt;/span&gt;
      &lt;/button&gt;
    &lt;/div&gt;
    &lt;span hidden data-code-scroll-hint class=&#34;order-last w-full pb-2 [[hidden]]:hidden&#34;&gt;Scroll horizontally &lt;span aria-hidden=&#34;true&#34;&gt;↔&lt;/span&gt;&lt;/span&gt;
  &lt;/figcaption&gt;
  &lt;p data-code-target=&#34;status&#34; role=&#34;status&#34; class=&#34;sr-only m-0 px-5 pt-3 text-xs leading-relaxed text-[#b8c2d1] desktop:px-7&#34;&gt;&lt;/p&gt;
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre aria-labelledby=&#34;code-label-0&#34; tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;button&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;document&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;querySelector&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;button&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;button&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;addEventListener&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;click&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;onClick&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;console&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;clicked&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;button&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;removeEventListener&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;click&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;onClick&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;});&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/figure&gt;</description>
    </item>
    
    <item>
      <title>Rename Fields by Using Aliases in GraphQL</title>
      <link>https://devinschulz.com/blog/rename-fields-by-using-aliases-in-graphql/</link>
      <guid>https://devinschulz.com/blog/rename-fields-by-using-aliases-in-graphql/</guid>
      <pubDate>Sun, 05 Jul 2020 00:00:00 &#43;0000</pubDate>
      <description>&lt;p&gt;When working with a GraphQL API, you may want to rename a field to something
other than what the API has to offer. Aliases exist as part of the GraphQL spec
to solve this exact problem.&lt;/p&gt;
&lt;p&gt;Aliases allow you to rename a single field to whatever you want it to be. They
are defined client-side, so you don&amp;rsquo;t need to update your API to use them.&lt;/p&gt;
&lt;p&gt;Imagine requesting data using the following query from an API:&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Filter Out Multiple Console Messages in Google Chrome</title>
      <link>https://devinschulz.com/blog/filter-out-multiple-console-messages-in-google-chrome/</link>
      <guid>https://devinschulz.com/blog/filter-out-multiple-console-messages-in-google-chrome/</guid>
      <pubDate>Fri, 01 May 2020 00:00:00 &#43;0000</pubDate>
      <description>&lt;p&gt;Google Chrome gives you the ability to filter out messages within the console by
prefixing a search term with the hyphen-minus (subtraction) character &lt;code&gt;-&lt;/code&gt;. If
you want to ignore multiple entries, add a space between the search terms.&lt;/p&gt;
&lt;figure class=&#34;code-block not-prose my-8 min-w-0 overflow-hidden rounded-xl border border-white/10 bg-[#171a20] text-[13px] leading-[1.7] text-[#eee] [&amp;_pre]:m-0 [&amp;_pre]:max-w-full [&amp;_pre]:overflow-x-auto [&amp;_pre]:bg-transparent [&amp;_pre]:p-5 desktop:[&amp;_pre]:p-7 [&amp;_pre:focus-visible]:outline-2 [&amp;_pre:focus-visible]:outline-offset-[-3px] [&amp;_pre:focus-visible]:outline-white [&amp;_pre:focus-visible]:ring-0 forced-colors:[&amp;_pre:focus-visible]:outline-[Highlight] [&amp;_code]:font-mono [&amp;_code]:text-[inherit]&#34; data-controller=&#34;code&#34; data-action=&#34;keydown-&gt;code#scroll turbo:before-cache@document-&gt;code#clear&#34;&gt;
  &lt;figcaption class=&#34;flex min-h-11 flex-wrap items-center justify-between gap-x-4 border-b border-white/10 px-5 text-xs text-[#b8c2d1] desktop:px-7&#34;&gt;
    &lt;span id=&#34;code-label-0&#34; class=&#34;font-mono&#34;&gt;Plain text&lt;/span&gt;
    &lt;div class=&#34;ml-auto flex items-center gap-3&#34;&gt;
      &lt;span class=&#34;font-mono&#34; aria-hidden=&#34;true&#34;&gt;.txt&lt;/span&gt;
      &lt;button hidden type=&#34;button&#34; data-code-target=&#34;button&#34; data-action=&#34;code#copy&#34; aria-label=&#34;Copy Plain text code&#34; class=&#34;group/copy inline-flex min-h-11 min-w-18 items-center justify-center rounded-md font-sans text-xs text-[#eee] disabled:cursor-wait disabled:opacity-60 focus-visible:outline-2 focus-visible:outline-offset-[-3px] focus-visible:outline-white focus-visible:ring-0 forced-colors:focus-visible:outline-[Highlight] [[hidden]]:hidden&#34;&gt;
        &lt;span class=&#34;pointer-events-none inline-flex min-h-7 min-w-18 shrink-0 items-center justify-center gap-1.5 rounded-md border border-white/15 px-1.5 whitespace-nowrap group-hover/copy:bg-white/10&#34;&gt;
          &lt;svg data-code-target=&#34;copyIcon&#34; class=&#34;shrink-0&#34; width=&#34;12&#34; height=&#34;12&#34; viewBox=&#34;0 0 16 16&#34; fill=&#34;none&#34; stroke=&#34;currentColor&#34; stroke-width=&#34;1.25&#34; aria-hidden=&#34;true&#34;&gt;&lt;rect x=&#34;5&#34; y=&#34;5&#34; width=&#34;9&#34; height=&#34;9&#34; rx=&#34;1.5&#34;/&gt;&lt;path d=&#34;M3 11H2.5A1.5 1.5 0 0 1 1 9.5v-7A1.5 1.5 0 0 1 2.5 1h7A1.5 1.5 0 0 1 11 2.5V3&#34;/&gt;&lt;/svg&gt;
          &lt;svg hidden data-code-target=&#34;checkIcon&#34; class=&#34;shrink-0 [[hidden]]:hidden&#34; width=&#34;12&#34; height=&#34;12&#34; viewBox=&#34;0 0 16 16&#34; fill=&#34;none&#34; stroke=&#34;currentColor&#34; stroke-width=&#34;1.5&#34; aria-hidden=&#34;true&#34;&gt;&lt;path d=&#34;m3 8 3 3 7-7&#34;/&gt;&lt;/svg&gt;
          &lt;span data-code-target=&#34;label&#34; class=&#34;shrink-0 whitespace-nowrap&#34;&gt;Copy&lt;/span&gt;
        &lt;/span&gt;
      &lt;/button&gt;
    &lt;/div&gt;
    &lt;span hidden data-code-scroll-hint class=&#34;order-last w-full pb-2 [[hidden]]:hidden&#34;&gt;Scroll horizontally &lt;span aria-hidden=&#34;true&#34;&gt;↔&lt;/span&gt;&lt;/span&gt;
  &lt;/figcaption&gt;
  &lt;p data-code-target=&#34;status&#34; role=&#34;status&#34; class=&#34;sr-only m-0 px-5 pt-3 text-xs leading-relaxed text-[#b8c2d1] desktop:px-7&#34;&gt;&lt;/p&gt;
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre aria-labelledby=&#34;code-label-0&#34; tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;-term -analytics&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/figure&gt;</description>
    </item>
    
    <item>
      <title>Restrictions While Styling Visited Links</title>
      <link>https://devinschulz.com/blog/restrictions-while-styling-visited-links/</link>
      <guid>https://devinschulz.com/blog/restrictions-while-styling-visited-links/</guid>
      <pubDate>Tue, 18 Feb 2020 00:00:00 &#43;0000</pubDate>
      <description>&lt;p&gt;The &lt;code&gt;:visited&lt;/code&gt; pseudo-class is a unique state that provides visible feedback on
links that a user has navigated to. This state behaves similarly to other
pseudo-classes like &lt;code&gt;:hover&lt;/code&gt;, &lt;code&gt;:focus&lt;/code&gt;, and &lt;code&gt;:active&lt;/code&gt;, but comes with a few
limitations.&lt;/p&gt;
&lt;h2 id=&#34;limitations&#34;&gt;Limitations&lt;/h2&gt;
&lt;p&gt;First and foremost, you can only change the CSS properties of a visited link if
the unvisited link already has that style applied. If your unvisited link does
not have a background color, but the visited one does, it will &lt;strong&gt;not&lt;/strong&gt; apply
that background color. If your unvisited link has a background color, and you
change that color for visited links, it &lt;strong&gt;will&lt;/strong&gt; work.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Modify Create React App&#39;s Babel Configuration Without Ejecting</title>
      <link>https://devinschulz.com/blog/modify-create-react-apps-babel-configuration-without-ejecting/</link>
      <guid>https://devinschulz.com/blog/modify-create-react-apps-babel-configuration-without-ejecting/</guid>
      <pubDate>Sun, 02 Feb 2020 00:00:00 &#43;0000</pubDate>
      <description>&lt;p&gt;I love using &lt;a href=&#34;https://github.com/facebook/create-react-app&#34;&gt;Create React App&lt;/a&gt; to
spin up an application swiftly, but one annoyance I keep running into is not being able to modify the Babel configuration. Why would you want to do
this? Perhaps you want to use some of the latest ES.next features before they&amp;rsquo;re
approved and merged into Create React App. In this case, you could &lt;a href=&#34;https://create-react-app.dev/docs/available-scripts/#npm-run-eject&#34;&gt;eject&lt;/a&gt; the app, but there are several reasons you might not want to.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>I&#39;ve Lost Faith in Client-Side Analytics</title>
      <link>https://devinschulz.com/blog/ive-lost-faith-in-client-side-analytics/</link>
      <guid>https://devinschulz.com/blog/ive-lost-faith-in-client-side-analytics/</guid>
      <pubDate>Sat, 31 Aug 2019 00:00:00 &#43;0000</pubDate>
      <description>&lt;p&gt;I&amp;rsquo;ve been using Google Analytics on this website since its inception, and
according to W3Techs,
&lt;a href=&#34;https://w3techs.com/technologies/details/ta-googleanalytics/all/all&#34;&gt;56.4 percent of sites on the internet&lt;/a&gt;
do too. I use the data collected from Google Analytics to see which posts are popular and which features are used most often. If a particular article is more
popular than others, I&amp;rsquo;ll make sure to write more about that subject in the
future. If a specific feature is rarely used, I&amp;rsquo;ll most likely remove it.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Accumulate Complex Objects With the Reduce Method</title>
      <link>https://devinschulz.com/blog/accumulate-complex-objects-with-the-reduce-method/</link>
      <guid>https://devinschulz.com/blog/accumulate-complex-objects-with-the-reduce-method/</guid>
      <pubDate>Mon, 29 Jul 2019 00:00:00 &#43;0000</pubDate>
      <description>&lt;p&gt;Many people don&amp;rsquo;t realize the power and potential of the &lt;code&gt;Array.reduce&lt;/code&gt;
(&lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce&#34;&gt;MDN&lt;/a&gt;)
method. What makes it so powerful is its ability to take in an array containing
any values and then return almost any type of data. Because of this flexibility,
I want to highlight one technique you can use to traverse an array containing any number of nested objects. You&amp;rsquo;ll learn how to accumulate all objects
and return a single object you can use to reference any entry by ID.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Building the Inspect Measurement Engine</title>
      <link>https://devinschulz.com/blog/building-the-inspect-measurement-engine/</link>
      <guid>https://devinschulz.com/blog/building-the-inspect-measurement-engine/</guid>
      <pubDate>Wed, 17 Jul 2019 00:00:00 &#43;0000</pubDate>
      <description>&lt;p&gt;Not too long ago, I had the opportunity to build a measurement system inside Inspect that calculates and displays the distances between two layers. Between the layers, a line is drawn with a label that displays the distance.
Supporting lines are added to the nearest edges of the hovered layer to help give the user an idea of where the measurement lines reach.&lt;/p&gt;
&lt;p&gt;In this article, I&amp;rsquo;ll explain some of my ideas and how I managed to take a
fairly complex problem, break it down, and deliver something of value to an end
user. I hope that after reading this article, you&amp;rsquo;ll have a better understanding of how to dissect a problem you may be facing. I know that when I was handed the ticket to implement this functionality, I found it intimidating.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>From Hugo to Next.js and Back Again</title>
      <link>https://devinschulz.com/blog/from-hugo-to-next-js-and-back-again/</link>
      <guid>https://devinschulz.com/blog/from-hugo-to-next-js-and-back-again/</guid>
      <pubDate>Sat, 18 May 2019 00:00:00 &#43;0000</pubDate>
      <description>&lt;p&gt;This post covers my challenges, my frustrations, and why I ultimately landed on
using Hugo as a static site generator to build my blog. The past three
iterations of this website were written using Hugo, then Next.js, and then Hugo again. Hugo gave me so much out of the box, and practically everything I
needed, whereas Next.js required me to write the functionality I wanted
explicitly. This article isn&amp;rsquo;t meant to hate on any framework; it&amp;rsquo;s just my own experience.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Reflecting on Four Years of Remote Work</title>
      <link>https://devinschulz.com/blog/reflecting-on-four-years-of-remote-work/</link>
      <guid>https://devinschulz.com/blog/reflecting-on-four-years-of-remote-work/</guid>
      <pubDate>Tue, 12 Mar 2019 00:00:00 &#43;0000</pubDate>
      <description>&lt;p&gt;Throughout the past four years, I&amp;rsquo;ve had the opportunity to work for a unique, design-focused company called &lt;a href=&#34;https://invisionapp.com&#34;&gt;InVision&lt;/a&gt;. For those not
familiar with InVision, it is growing to be the operating system for digital
product design. Its product line provides tools for designers, developers, and
stakeholders to collaborate on designing and building websites, mobile
applications, and almost anything else that is displayed on a screen.&lt;/p&gt;
&lt;p&gt;The entire company is dispersed across the globe with people across all
continents and in almost all time zones. There is no central office, but some
make use of co-working spaces like WeWork. All communication happens on Slack and
meetings take place on Zoom.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Building a Likes API With Google Cloud Functions</title>
      <link>https://devinschulz.com/blog/building-a-likes-api-with-google-cloud-functions/</link>
      <guid>https://devinschulz.com/blog/building-a-likes-api-with-google-cloud-functions/</guid>
      <pubDate>Mon, 05 Nov 2018 21:41:18 -0400</pubDate>
      <description>&lt;p&gt;I took on the challenge of building a like button into this blog. Since the site is
compiled and then deployed as flat files, there is no backend or database to
manage. From a security standpoint, there is no safer way to develop a website, but
it does add a bit of complexity to incorporate dynamic content.&lt;/p&gt;
&lt;p&gt;My first attempt was to add Firebase as a dependency and wire it up to the likes
button. This worked great as it gave me real-time updates across multiple
browser sessions whenever I clicked the button. However, looking at the
compiled, minified bundle, I noticed it had added over 220 KB!&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Copy React Props to Your Clipboard in Google Chrome</title>
      <link>https://devinschulz.com/blog/copy-react-props-to-your-clipboard-in-google-chrome/</link>
      <guid>https://devinschulz.com/blog/copy-react-props-to-your-clipboard-in-google-chrome/</guid>
      <pubDate>Sat, 14 Jul 2018 12:26:27 -0400</pubDate>
      <description>&lt;p&gt;While working on a React project today, I was looking to copy a property passed down to a component. After searching around, I found out it&amp;rsquo;s
surprisingly easy.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Open up the
&lt;a href=&#34;https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en&#34;&gt;React Developer Tools&lt;/a&gt;
tab within the Chrome inspector.




  
    
    
    &lt;img src=&#34;https://devinschulz.com/images/blog/step1_hu_a0f8c528ca4287e4.webp&#34; srcset=&#34;https://devinschulz.com/images/blog/step1_hu_a0f8c528ca4287e4.webp 636w&#34; sizes=&#34;(min-width: 781px) 660px, calc(100vw - 34px)&#34; alt=&#34;Step one, selecting the React tab within the Google Chrome developer tools&#34; width=&#34;636&#34; height=&#34;159&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34;&gt;
  

&lt;/li&gt;
&lt;li&gt;Select the component or element that contains the property you want to copy.




  
    
    
    &lt;img src=&#34;https://devinschulz.com/images/blog/step23_hu_9ebd2627fdb59cc1.webp&#34; srcset=&#34;https://devinschulz.com/images/blog/step23_hu_9ebd2627fdb59cc1.webp 638w&#34; sizes=&#34;(min-width: 781px) 660px, calc(100vw - 34px)&#34; alt=&#34;Step two and three, selecting a component and then right-clicking the indicator&#34; width=&#34;638&#34; height=&#34;330&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34;&gt;
  

&lt;/li&gt;
&lt;li&gt;Right-click the &lt;code&gt;{…}&lt;/code&gt; and select &lt;strong&gt;Store as global variable&lt;/strong&gt; from the menu.&lt;/li&gt;
&lt;li&gt;Navigate to the console tab.




  
    
    
    &lt;img src=&#34;https://devinschulz.com/images/blog/step45_hu_3e244e0c072134cb.webp&#34; srcset=&#34;https://devinschulz.com/images/blog/step45_hu_3e244e0c072134cb.webp 656w&#34; sizes=&#34;(min-width: 781px) 660px, calc(100vw - 34px)&#34; alt=&#34;Step four and five, navigating to the console tab and then taking notice of a new variable.&#34; width=&#34;656&#34; height=&#34;171&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34;&gt;
  

&lt;/li&gt;
&lt;li&gt;You will notice a global variable was added with a naming convention similar
to &lt;code&gt;$tmp&lt;/code&gt; or &lt;code&gt;temp1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Copy the value to your clipboard by typing &lt;code&gt;copy($tmp)&lt;/code&gt; into the console.




  
    
    
    &lt;img src=&#34;https://devinschulz.com/images/blog/step6_hu_175183f564022914.webp&#34; srcset=&#34;https://devinschulz.com/images/blog/step6_hu_175183f564022914.webp 638w&#34; sizes=&#34;(min-width: 781px) 660px, calc(100vw - 34px)&#34; alt=&#34;Step 6, copying the value to your clipboard&#34; width=&#34;638&#34; height=&#34;184&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34;&gt;
  

&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;What&amp;rsquo;s great about this trick is almost any value that has the &lt;code&gt;{…}&lt;/code&gt; beside it
within the Chrome inspector can be set as a global variable. Therefore, this
method is not limited to the React Developer Tools.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Combining Synchronous Actions Using Redux Thunk</title>
      <link>https://devinschulz.com/blog/combining-synchronous-actions-using-redux-thunk/</link>
      <guid>https://devinschulz.com/blog/combining-synchronous-actions-using-redux-thunk/</guid>
      <pubDate>Mon, 09 Jul 2018 16:20:02 -0400</pubDate>
      <description>&lt;p&gt;Simple frontend applications I&amp;rsquo;ve worked with have one event (click, keypress,
input change, etc.) that dispatches a single action to modify part of the
application state tree. As your application grows in complexity, that single event may need to perform several actions at once and run some sort of business logic before they are dispatched.&lt;/p&gt;
&lt;h2 id=&#34;a-potential-solution&#34;&gt;A Potential Solution&lt;/h2&gt;
&lt;p&gt;Recently I&amp;rsquo;ve been using &lt;a href=&#34;https://github.com/reduxjs/redux-thunk&#34;&gt;Redux Thunk&lt;/a&gt;
for dispatching a single thunk action, and in turn, it dispatches several
actions to modify independent areas of the application state. Think Redux Thunk
is only for asynchronous actions? Think again! Never heard of Redux Thunk or the
term thunk? No worries, I will go a bit more in-depth about how it works below.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Welcome Readers</title>
      <link>https://devinschulz.com/blog/welcome-readers/</link>
      <guid>https://devinschulz.com/blog/welcome-readers/</guid>
      <pubDate>Sun, 17 Jun 2018 00:00:00 &#43;0000</pubDate>
      <description>&lt;p&gt;I&amp;rsquo;m a designer turned web developer who specializes in frontend applications.
As an advocate for best practices and proper semantics, I believe that the web
should be open and accessible for everyone.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve struggled for years to get a decent blog up and running. It wasn&amp;rsquo;t because of a lack of content. On the contrary, the design was the obstacle. I designed countless mockups and developed fully functioning
prototypes, but they never entirely made the cut. I was so critical of everything
I designed; I always found something that I didn&amp;rsquo;t like, and then found myself
rejecting each concept.&lt;/p&gt;</description>
    </item>
    
  </channel>
</rss>
