<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Rohov Dmytro</title>
    <description>The latest articles on DEV Community by Rohov Dmytro (@rohovdmytro).</description>
    <link>https://dev.to/rohovdmytro</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F50865%2Fc920b064-2204-4cc6-8d5d-3dd8803cf702.jpg</url>
      <title>DEV Community: Rohov Dmytro</title>
      <link>https://dev.to/rohovdmytro</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rohovdmytro"/>
    <language>en</language>
    <item>
      <title>Friday Quick Tips — Use package.json As a Shortcut Holder</title>
      <dc:creator>Rohov Dmytro</dc:creator>
      <pubDate>Fri, 29 May 2020 05:51:52 +0000</pubDate>
      <link>https://dev.to/rohovdmytro/fridaytinytips-use-package-json-as-a-shortcut-holder-651</link>
      <guid>https://dev.to/rohovdmytro/fridaytinytips-use-package-json-as-a-shortcut-holder-651</guid>
      <description>&lt;p&gt;Really quick tip for today.&lt;/p&gt;

&lt;p&gt;I've been programming using Node.js for quite a while now. Six, seven years? Damn. And only in recent projects I've started to «save» common scripts as a yarn «shortcuts». Damn++!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Flva87jxykww6eaa41py0.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Flva87jxykww6eaa41py0.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's extremely simple. Simple as that:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fh256tze99xnz8xc9u1dz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fh256tze99xnz8xc9u1dz.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Every morning it makes me a couple of presses away from a Carpal tunnel syndrome! Nice!&lt;/p&gt;

&lt;p&gt;That's it. That simple tip.&lt;/p&gt;

&lt;p&gt;Yours, truly, RG, on his way from &lt;a href="https://blog.swingpulse.com" rel="noopener noreferrer"&gt;consumer to creator&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Save the clicks for something more meaningful!&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>webdev</category>
      <category>node</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Mind Hacks — Being More Productive &amp; Avoiding Pitfalls</title>
      <dc:creator>Rohov Dmytro</dc:creator>
      <pubDate>Thu, 14 May 2020 09:57:11 +0000</pubDate>
      <link>https://dev.to/rohovdmytro/mind-hacks-to-be-more-productive-code-better-b30</link>
      <guid>https://dev.to/rohovdmytro/mind-hacks-to-be-more-productive-code-better-b30</guid>
      <description>&lt;p&gt;I have my own way to deal with productivity. I was calling them mind hacks, personal slogans and other weird names.&lt;/p&gt;

&lt;p&gt;When I'm feeling stuck, overwhelmed or finding myself in some «bad» pattern — I use those mind hacks.&lt;/p&gt;

&lt;p&gt;Recently I've found an «official» name for i. It's time to share. :) &lt;/p&gt;

&lt;p&gt;They are called «mottos».&lt;/p&gt;

&lt;p&gt;I have a very &lt;b&gt;special&lt;/b&gt; newsletter with &lt;b&gt;deep&lt;/b&gt; information about productivity, mind hacks &amp;amp; better thinking. &lt;a href="https://blog.swingpulse.com/"&gt;Boost yourself — join the force&lt;/a&gt;! 🤗&lt;/p&gt;

&lt;h2&gt;
  
  
  Welcome, Mottos
&lt;/h2&gt;

&lt;p&gt;What the hell is a motto?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The motto is a short sentence or phrase chosen as encapsulating the beliefs or ideals of an individual, family, or institution.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Simple said: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Motto is a personal slogan.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When I find myself on a slippery road to breaking a good coding habit — I use a certain motto to help me out. And usually, its impact is enough to win the battle.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Battle Of Optimization
&lt;/h2&gt;

&lt;p&gt;I've coined the problem of pre-mature optimization into this phrase:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Do not optimize the future, optimize the past.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;THIS wording works for me. It should not work for you. And that is the whole point. To remember certain rules with wording that works for you.&lt;/p&gt;

&lt;p&gt;My attitude to pre-mature optimization is that. I want to optimize stuff  that is already happened. On other words my optimization should be based on data. And data comes from the past. :) &lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem of Choice
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Choice is good. Choosing is NOT.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Having tons of frameworks, libraries, and options is cool. But making a perfect decision eats up way too much energy. And some cases it's valid, but in most it's not. Things change.&lt;/p&gt;

&lt;p&gt;I simply try to avoid choosing.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem of Tooling
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Don't look for a better tool, seek for a better brain.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I've stopped mindlessly replacing my inner problems with better tooling and addons and seeking to improve myself first (at least trying), then seek for the tools.&lt;/p&gt;

&lt;h2&gt;
  
  
  Designing Your Own Mottos
&lt;/h2&gt;

&lt;p&gt;We all have encountered different thoughts that move us. Thіs information is extremely valuable.&lt;/p&gt;

&lt;p&gt;Shape it, support it, use it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Shape it. Support it. Use it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Be careful. Mottos are NOT about what you WANT to believe. They are about your current beliefs, not the future ones. Just be careful NOT to pick fancy stuff that looks nice but doesn't really click with you. Be honest with yourself.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Shape it&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Identify what you strongly believe in and coin that into a short sentence. &lt;/p&gt;

&lt;p&gt;It all starts with noticing.&lt;/p&gt;

&lt;p&gt;Once I've noticed how important it is for me to build up positive momentum in the morning, I have zero doubts that it is my thing. It is my thing. It's important for me, period.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Mornings are about momentum.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Write down your strongest beliefs — things, that are deeply connected to you and have a real impact on your behavior.&lt;/p&gt;

&lt;p&gt;If you're feeling like it — feel free to steal someone's phrasing, easily. It's yours if it's yours. Pay attention. When you consume content and a phrase strikes your heart — write it down. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Ready. Set. Go!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the beginning, it's not THAT important how well they are articulated.  It's what you put into the sentence, the personal meaning.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Support&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;What makes a motto more powerful is what it's connected to. Think Coca Cola putting billions of dollars into advertising to support its brand. You might also want to support your personal slogans. They should be deeply connected with your goals, beliefs, emotions. &lt;/p&gt;

&lt;p&gt;Write that down.&lt;/p&gt;

&lt;p&gt;Mottos are powered by both rational and irrational. Rational arguments and emotional coloring make a cool combo. In other words:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Can you explain your belief?&lt;/li&gt;
&lt;li&gt;Does it excite you?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When you consume the content you might come across stuff that supports your motto. For example, when I've persuaded myself (made it an internal belief) that consistency is important I hear it from almost every person I follow. Consistently.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use Them&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Bring your motto to life and use it as a weapon contextually. It's your tool, your beliefs. Use accordingly. &lt;/p&gt;

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

&lt;p&gt;It takes time to shape your worldview and find internal hacks, but it's totally worth it. Shape your beliefs concisely in order to use them effectively. Support them with internal and external evidence and you will become better, faster, and stronger.&lt;/p&gt;

&lt;p&gt;Mottos are not a magic wand, but the world is complex enough so we can neglect what we actually believe. These reminders are a powerful mechanism to identify yourself and navigate life better.&lt;/p&gt;

&lt;p&gt;Just do it.&lt;/p&gt;

&lt;p&gt;And hey! I post some deep cool stuff on my newsletter. &lt;a href="https://blog.swingpulse.com/"&gt;Join the 200+ mind hackers&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;What is your motto and what is the background behind it?&lt;/em&gt;&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>mentalhealth</category>
    </item>
    <item>
      <title>#discuss What is your top 3 mindset hacks for being a more productive developer?</title>
      <dc:creator>Rohov Dmytro</dc:creator>
      <pubDate>Thu, 07 May 2020 22:49:18 +0000</pubDate>
      <link>https://dev.to/rohovdmytro/discuss-what-is-your-top-3-mindset-hacks-for-being-a-more-productive-developer-oka</link>
      <guid>https://dev.to/rohovdmytro/discuss-what-is-your-top-3-mindset-hacks-for-being-a-more-productive-developer-oka</guid>
      <description>&lt;h3&gt;
  
  
  Mine Top 3
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Asking myself: «What am I doing» (&amp;amp; switching focus back to the task :))&lt;/li&gt;
&lt;li&gt;Loosen up my attitude to all that jazz like file organization, editor colors, plugins, naming convention.&lt;/li&gt;
&lt;li&gt;Reminding myself that tools should serve me, not the other way&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Yours?&lt;/p&gt;

</description>
      <category>productivity</category>
    </item>
    <item>
      <title>10 Tips To Get Out Of Your Own Way And Start That Side Project</title>
      <dc:creator>Rohov Dmytro</dc:creator>
      <pubDate>Tue, 05 May 2020 10:31:44 +0000</pubDate>
      <link>https://dev.to/rohovdmytro/start-doing-your-dream-project-here-s-what-works-for-me-4ff8</link>
      <guid>https://dev.to/rohovdmytro/start-doing-your-dream-project-here-s-what-works-for-me-4ff8</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Let's START working on our «Dream Projects»!&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;My last 10 years of coding had its ups and downs. To have more ups I've implemented tiny habits to be more productive. It's time to share! If one of them will make you 1% more productive everyday — I am taking it!&lt;/p&gt;

&lt;p&gt;Beware! Some of the tips might be silly (or against best practices). But in my personal experience they DO make me more productive. At least in my case.&lt;/p&gt;

&lt;p&gt;And hey, ultimately, productivity is a speed of achieving our dreams. Let's do something about it!&lt;/p&gt;




&lt;h2&gt;
  
  
  How To Finally Start Doing Your Dream Project
&lt;/h2&gt;




&lt;p&gt;I am defining the problem of starting as a problem of mental walls. Let me explain.&lt;/p&gt;

&lt;p&gt;I have a medium size personal goal — to acquire 10 000 people to use my products that will help people to become MORE self-aware. THAT is my personal realistic dream. &lt;/p&gt;

&lt;p&gt;But! I am not sure which tools exactly I will build (AND people will use). Not cool. And understanding yourself in not an easy task. But in order to figure out the tool to build I need to iterate on my ideas (and hypothesizes). And in order to iterate I need to... start and to... finish. &lt;/p&gt;

&lt;p&gt;To start the WHOLE project and to finish the whole project. Daaamn. :) &lt;/p&gt;

&lt;p&gt;I want my week to look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--g42AP7WF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/bav98bme9jjs3see4cgh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--g42AP7WF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/bav98bme9jjs3see4cgh.png" alt="Schedule"&gt;&lt;/a&gt;&lt;br&gt;
And NOT like this (irony):&lt;/p&gt;

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

&lt;p&gt;Hey, naming convention of my variables IS important (from some perspective). But while looking at a bigger picture there are more important problems I want to face. For example. Am I delivering real value to the people with my products?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Mental bottlenecks are the places we feel like we need to make a good decision but it might not be THAT important from a bigger stand point.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;My opinion:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;One the most most important meta-skills is the ability to start and to finish.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Cause overthinking is not fun. Momentum is!&lt;/p&gt;

&lt;p&gt;And hey, hey, hey! I'm sharing my real-life experience. IF you are interested in building side projects that would challenge you to become better &amp;amp; stronger — &lt;a href="https://blog.swingpulse.com"&gt;join me, join my newsletter&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To the tips.&lt;/p&gt;

&lt;h1&gt;
  
  
  Tips
&lt;/h1&gt;




&lt;h2&gt;
  
  
  Picking The Idea
&lt;/h2&gt;

&lt;p&gt;We need good idea. But good ideas does not come from nowhere. They should be based on something. So my current idea is not based on data. I simply don't have real-life product data. That's why my current idea is simply based on intuition (consider this as an inner source of data). &lt;/p&gt;

&lt;p&gt;The idea is: tracking daily stuff in a fun way using... emojis.&lt;/p&gt;

&lt;p&gt;And then I am telling myself:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Let's spend some quality time to find the perfect shape for this idea in order to test it in the wild.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let your first idea be based on intuition. You will get experience and data later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Naming is hard. Avoid it!
&lt;/h2&gt;

&lt;p&gt;Naming a project is hard. But it should not be hard to name things while in active development. What I do is I give temporary technical names. For this project I chose the name «Trackerion».&lt;/p&gt;

&lt;p&gt;Sometimes I name projects literally. My previous project was called: «habits-with-feelings».&lt;/p&gt;

&lt;p&gt;And that is fine. You might have a perfect name while working or talking to people. Just don't get stuck with this initially.&lt;/p&gt;

&lt;h2&gt;
  
  
  Biggest Tip To File Organization
&lt;/h2&gt;

&lt;p&gt;All I am starting is a single file — App.js. And only later — everything.js else on/demand.js. And that is fine. The structure will happen later.&lt;/p&gt;

&lt;p&gt;And that's all.&lt;/p&gt;

&lt;h2&gt;
  
  
  Don't Stuck With Your Tools
&lt;/h2&gt;

&lt;p&gt;I can easy imagine this conversation, happening in heaven:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;— What was the last thing that you remember?&lt;br&gt;
— npm install&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sometimes you can get older while installing all the android tooling or NPM packages. But there is a hack. Don't get stuck with your tools! Do other stuff in the context of the current task / project.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Visualize the problem&lt;/li&gt;
&lt;li&gt;Plan the code&lt;/li&gt;
&lt;li&gt;Priorities features&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aRm6nVDD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/akuujrzf35q7e40mghgg.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aRm6nVDD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/akuujrzf35q7e40mghgg.jpg" alt="Super ultra prototype"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For example, while some script was spinning, I've started exploring uploading my app to the Google Play Store and this is what I've found.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AYkb-DL7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/onlfea5hfbzbkfs0l5hy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AYkb-DL7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/onlfea5hfbzbkfs0l5hy.png" alt="Warning"&gt;&lt;/a&gt;&lt;br&gt;
This simple act won be a couple of days because I've realised that I need to upload my app as soon as I can.&lt;/p&gt;

&lt;p&gt;Don't stuck with your tools. There is always something useful.&lt;/p&gt;

&lt;h2&gt;
  
  
  Expect The Unexpected Things
&lt;/h2&gt;

&lt;p&gt;So I was at the peak of excitement during the development when my phone's screen got smashed. And I've just set up everything to develop with it.&lt;/p&gt;

&lt;p&gt;Yikes!&lt;/p&gt;

&lt;p&gt;How to win in this situation? &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The win is to put as least attention to the bad news and keep going.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Found my very old phone, set up everything again, send my broken phone to the fastest repair service.&lt;/p&gt;

&lt;p&gt;Feeling sad, feeling bad, accepting life, moving on.&lt;/p&gt;

&lt;h2&gt;
  
  
  Minimise Style Fapping
&lt;/h2&gt;

&lt;p&gt;This one is golden. I think this rule is one the biggest time saver for me. This rule saved me DOZENS of hours.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Don't. Play. With. Styles.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I've stopped tweaking paddings, margins, colors etc. For some reason I was doing this during the active development.&lt;/p&gt;

&lt;p&gt;No-no-no-no.&lt;/p&gt;

&lt;p&gt;Instead, I have this rule:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Put UI blocks onto their places.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Minimising time to tweak styles, tweaking. Focusing on building a clear screen/page structure.&lt;/p&gt;

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

&lt;p&gt;&lt;code&gt;color: green&lt;/code&gt; is fine, &lt;code&gt;color: red&lt;/code&gt; is fine.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resist The Urge Of Upgrading To The Latest &amp;amp; Greatest
&lt;/h2&gt;

&lt;p&gt;Upgrading to «latest and greatest» is... tricky. Cause you ofter run into some compatibility issues... &lt;/p&gt;

&lt;p&gt;Upgrading feels good, dealing with issues takes time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Landing Page — Just Find The Reference
&lt;/h2&gt;

&lt;p&gt;To complete a basic version of the landing app I usually go with some clear reference.&lt;/p&gt;

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

&lt;p&gt;You can transform doing a landing page into a rocket science, it is important. But you are fine to start having the basics.&lt;/p&gt;

&lt;p&gt;Done is better than perfect.&lt;/p&gt;

&lt;h2&gt;
  
  
  Have a Distraction Paper
&lt;/h2&gt;

&lt;p&gt;When I write on a piece of paper solving a particular task, I always get somewhat irrelevant thoughts. They feel good, but they are distracting. The solution is to have a «distraction paper». That paper where you write «everything else».&lt;/p&gt;

&lt;p&gt;It really, really, really helps.&lt;/p&gt;

&lt;h2&gt;
  
  
  Manage Technical Challenges
&lt;/h2&gt;

&lt;p&gt;This one is a big one.&lt;/p&gt;

&lt;p&gt;I've noticed a tendency to look for technical challenges. Yeah, learning as a programmer is fun. But here is a tricky part: it is not nesesarry helps you to finish. If you have a clear goal to learn something new — that is fine. But otherwise it's not wise.&lt;/p&gt;

&lt;p&gt;While you are some fancy term shared by a speaker who was solving a $ 100k business problem, time goes by. &lt;/p&gt;

&lt;p&gt;Every step can contain a challenge that can take weeks or months. And that is a lot of time!&lt;/p&gt;

&lt;h2&gt;
  
  
  Build The Everyday Momentum With Some Sweet Stuff
&lt;/h2&gt;

&lt;p&gt;Most of the time I am quite strict with myself in terms how I spend my time. But! If you have a bad mood... If things don't go so well... If it's an early morning and one cup of coffee was not enough...&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Gain momentum with some soul healing refactoring.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;:) &lt;/p&gt;

&lt;p&gt;or...&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Play with styles. A &lt;strong&gt;little&lt;/strong&gt; bit!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Cause we are all human beings.&lt;/p&gt;

&lt;p&gt;The End.&lt;/p&gt;

&lt;p&gt;This is part of the series. I have multiple ideas for the next articles! If you are interested in some of them — let me know in the comments.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How to overcome the middle launch crisis during the development. About restoring the faith in your project if it starts upsetting you. Basically, it's about a meta-skill of finishing. :)&lt;/li&gt;
&lt;li&gt;Why coder will NEVER launch a good product. This one is about different roles (hats) we should use to move forward with our personal projects. And a high price I've paid to understand that.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let me know in the comments! And if my words are relevant to you, follow me somewhere (or everywhere).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://twitter.com/rg_for_real"&gt;Twitter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/channel/UCeyCNhFmy-dhrrbByqBraPQ?view_as=subscriber"&gt;YouTube&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.swingpulse.com"&gt;Newsletter&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cheers!&lt;/p&gt;

&lt;p&gt;P.S. What stops you from starting?&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>sideprojects</category>
      <category>weddev</category>
    </item>
    <item>
      <title>#discuss Would you consider an external help (guidance) for your side project? In order to MAKE IT HAPPEN</title>
      <dc:creator>Rohov Dmytro</dc:creator>
      <pubDate>Tue, 17 Mar 2020 17:01:12 +0000</pubDate>
      <link>https://dev.to/rohovdmytro/discuss-would-you-consider-an-external-guidance-for-your-side-project-12e2</link>
      <guid>https://dev.to/rohovdmytro/discuss-would-you-consider-an-external-guidance-for-your-side-project-12e2</guid>
      <description>&lt;p&gt;I've been working as a programmer for 10+ years. And switched my current area of interest to dancing, teaching, blogging.&lt;/p&gt;

&lt;p&gt;I still do code, but now it's all about my personal projects that I personally need.&lt;/p&gt;

&lt;p&gt;And now I have this idea that inspires me SO much. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;To guide people while they are trying their side project happen.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Call it coaching, call it mentoring. &lt;/p&gt;

&lt;p&gt;The idea is simple. Helping people to overcome perfectionism. And make sure the project will be accomplished.&lt;/p&gt;

&lt;p&gt;Also, providing some perspective how to grow this side project into a bigger thing.&lt;/p&gt;

&lt;p&gt;Would YOU be interesting in this type of guidance?&lt;br&gt;
Would it be suitable for you to have a weekly chatting &amp;amp; guidance about your side project?&lt;br&gt;
Would you pay for this type of mentorship?&lt;/p&gt;

&lt;p&gt;What is your overall impression on this offer?&lt;/p&gt;

&lt;p&gt;Thank you in advance for your point of view!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>sideprojects</category>
      <category>coaching</category>
    </item>
    <item>
      <title>A Life Changing Hobby For a Programmer You Should Try</title>
      <dc:creator>Rohov Dmytro</dc:creator>
      <pubDate>Mon, 25 Nov 2019 14:55:54 +0000</pubDate>
      <link>https://dev.to/rohovdmytro/a-life-changing-hobby-for-a-programmer-you-should-try-19he</link>
      <guid>https://dev.to/rohovdmytro/a-life-changing-hobby-for-a-programmer-you-should-try-19he</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Online is great. Condensed human knowledge in just some clicks away. But what about human experience?.. This is what my post about. A way to balance an IT lifestyle.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Hello, beautiful people! I am working as a programmer for more than 10 years. And more than half of that time I have a hobby I want to describe to you and suggest to try out.&lt;/p&gt;

&lt;p&gt;It's called: Lindy Hop.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fdev8v3om3xrn7nuzes7i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fdev8v3om3xrn7nuzes7i.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And here is a social demo:&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/2hVkU23aOgk"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Generally speaking, it is a very pleasant way to spend your time. Let me share some of the reasons for it is a good idea to give it a try from a perspective of IT life.&lt;/p&gt;

&lt;h2&gt;
  
  
  #. It's an Opposite To Sitting
&lt;/h2&gt;

&lt;p&gt;We sit a lot. Sitting for a day is okay. Sitting for years is not. As IT-people we have lots of hours sitting.&lt;/p&gt;

&lt;p&gt;And dancing is definitely a physical activity. It can be demanding as you wish. You can dance to faster tempos or to slower one. Also you can be more lazy or more crazy.&lt;/p&gt;

&lt;h2&gt;
  
  
  #. Dancing is... fun.
&lt;/h2&gt;

&lt;p&gt;It is just fun. It puts a smile on your face.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Dancers were found to have higher levels of serotonin, known to boost moods in humans. ©&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When coding is more about brain, dancing is more about body.&lt;/p&gt;

&lt;h2&gt;
  
  
  #. Learning is... fun
&lt;/h2&gt;

&lt;p&gt;For me this is a big deal. The process of «figuring out» is a whole journey! Learning to dance is fun. Usually classes happen once or twice per week.&lt;/p&gt;

&lt;p&gt;Believe me, it is very different from staring at somebodies code. It makes your brain work in a totally different way. Which is gooood.&lt;/p&gt;

&lt;h2&gt;
  
  
  #. It's Easy
&lt;/h2&gt;

&lt;p&gt;You figure out the basics, you are ready to rock. It's up to you when you feel ready to nail at the dance floor. &lt;/p&gt;

&lt;h2&gt;
  
  
  #. It's Challenging
&lt;/h2&gt;

&lt;p&gt;It is also a challenge you are facing. It's putting yourself out there. Expressing yourself. «Dancing like nobody is watching».&lt;/p&gt;

&lt;h2&gt;
  
  
  #. It's a Worldwide Community
&lt;/h2&gt;

&lt;p&gt;There are hundreds (thousands?) of communities all around the world. And there are social events. Being part of the community means you have an additional purpose while travelling. And there are small and huge events across the globe. You can fly there, you can learn and party there. It. Is. Amazing.&lt;/p&gt;

&lt;h2&gt;
  
  
  #. It's Parties
&lt;/h2&gt;

&lt;p&gt;This is what's it's all about! I like to put it like this. Lindy Hop, for me, is a celebration of a human being. If this article resonated with you — consider giving it a shot.&lt;/p&gt;

&lt;p&gt;I believe to truly share everything it would be billion of reasons. I am doing this for more than 7 years. And hey! You should &lt;a href="https://www.instagram.com/rg.swing.dancer/" rel="noopener noreferrer"&gt;check my Instagram account&lt;/a&gt;. 🤗&lt;/p&gt;

&lt;p&gt;See you on a dance floor!&lt;/p&gt;

&lt;p&gt;[*] Photo credits go to &lt;a href="https://www.facebook.com/eric.esquivel.007?hc_location=ufi" rel="noopener noreferrer"&gt;Eric Esquivel&lt;/a&gt;. The dancers are &lt;a href="https://www.facebook.com/audrey.dasois?hc_location=ufi" rel="noopener noreferrer"&gt;Audrey Da Sois&lt;/a&gt; and &lt;a href="https://www.facebook.com/aurelien.lesdos?hc_location=ufi" rel="noopener noreferrer"&gt;Aurélien Lesdos&lt;/a&gt;.&lt;/p&gt;




</description>
      <category>balance</category>
      <category>health</category>
      <category>productivity</category>
      <category>mentalhealth</category>
    </item>
    <item>
      <title>How To Become a Better Programmer And Unblock Your Inspiring Ideas</title>
      <dc:creator>Rohov Dmytro</dc:creator>
      <pubDate>Thu, 06 Jun 2019 09:19:08 +0000</pubDate>
      <link>https://dev.to/rohovdmytro/how-to-become-a-better-programmer-and-unblock-your-inspiring-ideas-3e0k</link>
      <guid>https://dev.to/rohovdmytro/how-to-become-a-better-programmer-and-unblock-your-inspiring-ideas-3e0k</guid>
      <description>&lt;p&gt;A powerful insight of mine about hacking perfectionism, feeling better, more productive and unblocking myself to get things done.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Idea ⇒ Inspiration ⇒ Perfectionism ⇒ Block&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For example, you want to create a new web-service, you want to start a blog, youtube channel or write and article. It seems fun and exciting! But then «brain happens», nothing is done and you feel «blocked» or paralysed. Maybe this pattern happens too often and happens within years?&lt;/p&gt;

&lt;p&gt;Why so?&lt;/p&gt;

&lt;p&gt;Here is mine insight on why this is happening! At least in my case.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Mood represents the momentum. The momentum allows actions to flow. Perfectionism tends to change that mood, kills the momentum and makes doing a struggle.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let’s unwrap it.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;But before I would kindly suggest you to &lt;a href="https://blog.swingpulse.com/"&gt;check out&lt;/a&gt; my blog. There's some nice stuff over there!&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Mood As An Engine
&lt;/h1&gt;

&lt;p&gt;Once I’ve read a powerful opinion about the science of mood. And an insight I’ve experienced was this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Mood represents the momentum. Momentum leads to actions.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Momentum is like a wave you can climb and ride. It’s just so easier when it’s fun and joyful. It’s a really nice friend to accompany your actions.&lt;/p&gt;

&lt;p&gt;And it clicked for me.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The mood is not only nice to have. The mood is &lt;em&gt;quite a requirement&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You can definitely ignore it and fight through. But it’s totally different strategy.&lt;/p&gt;

&lt;h1&gt;
  
  
  Perfectionism as a Mood Killer
&lt;/h1&gt;

&lt;p&gt;My experience from a perspective of mood and momentum: perfectionism is their biggest nemesis!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The most common end result of perfectionism is a struggle to act&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Recognizing The Tradeoff
&lt;/h1&gt;

&lt;p&gt;It’s extremely hard for me to combine «perfect» and «fun». Fun vs perfect is a tradeoff I have to negotiate about with myself.&lt;/p&gt;

&lt;h2&gt;
  
  
  Recipe for productivity
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Recognize the power of mood on actions&lt;/li&gt;
&lt;li&gt;Protect the mood&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Question yourself
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Should you do stuff if you feel like shit doing it? Is it a path of becoming a better human or beating yourself until you break? Maybe it’s both?&lt;/li&gt;
&lt;li&gt;How does execution of the idea influence your mood?&lt;/li&gt;
&lt;li&gt;It is possible to combine having fun and perfectionism?&lt;/li&gt;
&lt;li&gt;What kills your mood?&lt;/li&gt;
&lt;li&gt;What about bad mood and momentum?&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Let the mood be with you!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Please, consider &lt;a href="https://blog.swingpulse.com/"&gt;checking out my website&lt;/a&gt; for more insights. You might find it valuable.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How To Improve Your Newsletter Subscription Flow (A Little Bit)</title>
      <dc:creator>Rohov Dmytro</dc:creator>
      <pubDate>Thu, 23 May 2019 14:53:52 +0000</pubDate>
      <link>https://dev.to/rohovdmytro/how-to-improve-your-newsletter-subscription-flow-a-little-bit-3m3m</link>
      <guid>https://dev.to/rohovdmytro/how-to-improve-your-newsletter-subscription-flow-a-little-bit-3m3m</guid>
      <description>&lt;p&gt;I like the idea of 1% regular improvements. In this post I will add describe how I've made a small improvement to my subscription experience in a Gatsby blog (with an open source plugin for you to use).&lt;/p&gt;

&lt;p&gt;This post is part of &lt;a href="https://blog.swingpulse.com/10x-better-gatsby"&gt;10x Better Gatsby&lt;/a&gt; Series. Go check it out!&lt;/p&gt;

&lt;h3&gt;
  
  
  The Idea
&lt;/h3&gt;

&lt;p&gt;Let people know that somebody is already trusts you. Lets show our credibility and authority by displaying current number of our newsletter subscribers.&lt;/p&gt;

&lt;p&gt;This is an example of what I am talking about:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vJwN6kVm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.swingpulse.com/static/eb0a81c955983a1991357329dabaf662/96300/example.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vJwN6kVm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.swingpulse.com/static/eb0a81c955983a1991357329dabaf662/96300/example.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Even a small community of readers is a community.&lt;/p&gt;

&lt;h3&gt;
  
  
  Open Source
&lt;/h3&gt;

&lt;p&gt;I've open sourced a really small plugin &lt;a href="https://github.com/rg4real/gatsby-source-mailchimp"&gt;@rogovdm/gatsby-source-mailchimp&lt;/a&gt; you can use to automate this task in a Gatsby blog. Usage is pretty straightforward (and is described in README).&lt;/p&gt;

&lt;p&gt;Like I said, it's a subtle change but those changes add up with time.&lt;/p&gt;

</description>
      <category>gatsby</category>
      <category>idea</category>
      <category>opensource</category>
      <category>newsletter</category>
    </item>
    <item>
      <title>Strong Will to Own Your Content in Era of Platforms</title>
      <dc:creator>Rohov Dmytro</dc:creator>
      <pubDate>Wed, 22 May 2019 12:17:22 +0000</pubDate>
      <link>https://dev.to/rohovdmytro/strong-will-to-own-your-content-5e5o</link>
      <guid>https://dev.to/rohovdmytro/strong-will-to-own-your-content-5e5o</guid>
      <description>&lt;p&gt;Do anyone strongly willing to have a personal website owning all of content and how it displays?&lt;/p&gt;

&lt;p&gt;I do want to. Something inside of me constantly resists to go all in on social media websites. I have hard time realizing that most of the content will be buried forever in a couple of days.&lt;/p&gt;

&lt;p&gt;Do anybody can relate to what I am saying?&lt;/p&gt;

&lt;p&gt;And the problem is that it's hard to compete with popular platforms for readers attention.&lt;/p&gt;

&lt;p&gt;What do you think about this topic?&lt;/p&gt;

</description>
      <category>discuss</category>
    </item>
    <item>
      <title>10 Things I Have Learned Open Sourcing A React Hook Without Going Crazy</title>
      <dc:creator>Rohov Dmytro</dc:creator>
      <pubDate>Tue, 21 May 2019 13:21:07 +0000</pubDate>
      <link>https://dev.to/rohovdmytro/10-things-i-have-learned-open-sourcing-a-react-hook-without-going-crazy-287g</link>
      <guid>https://dev.to/rohovdmytro/10-things-i-have-learned-open-sourcing-a-react-hook-without-going-crazy-287g</guid>
      <description>&lt;p&gt;This is my 10 gotchas how I spend tons of time open sourcing 100 LOC. And my attitude to swap frustration with just enough motivation to become 1% better. All of that while sharing some value with the world (via this post and an open source package).&lt;/p&gt;

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

&lt;p&gt;I had an idea to add a MailChimp subscription form to my blog via hooks. I thought it would be nice to isolate it into an open source package. 60 LOC for a hook and another 40 LOC for sloppy tests took surprisingly big amount of time.&lt;/p&gt;

&lt;p&gt;This post is part of my personal journey &lt;a href="https://blog.swingpulse.com/" rel="noopener noreferrer"&gt;you can join and learn for free&lt;/a&gt; from my mistakes.&lt;/p&gt;

&lt;h1&gt;
  
  
  Intention
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Resisting perfecting of every step to increase practicality and allowing myself to move forward, faster.&lt;/li&gt;
&lt;li&gt;Overcome rising complexities with reasonable amount of frustration.&lt;/li&gt;
&lt;li&gt;Document my discoveries.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  The result
&lt;/h1&gt;

&lt;p&gt;This is an usage example of &lt;a href="https://github.com/rg4real/react-use-mailchimp" rel="noopener noreferrer"&gt;react-use-mailchimp&lt;/a&gt; hook to embed a MailChimp form into a React app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;URL_YOU_CAN_OBRAIN_FROM_MAILCHIMP_UI&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reset&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useMailchimp&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setEmail&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;form&lt;/span&gt;
      &lt;span class="nx"&gt;onSubmit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;EMAIL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
      &lt;span class="p"&gt;}}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setEmail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt; &lt;span class="nx"&gt;onFocus&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;reset&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;submit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Submit&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;!!&lt;/span&gt;&lt;span class="nx"&gt;loading&lt;/span&gt;
          &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Loading...&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
          &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;
          &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Error during subscription&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
          &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;success&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
          &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Subscribed!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
          &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/form&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  My gotcha's
&lt;/h1&gt;

&lt;p&gt;Here is a list of my «gotchas» and takeaways during development.&lt;/p&gt;

&lt;h2&gt;
  
  
  #1. Configuring Jest
&lt;/h2&gt;

&lt;p&gt;From the beginning I've decided that I will have some tests, at least medium quality ones. Without thinking too hard I've checkout out open source code to see how people do their tests. What I found is a config that works for me:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;jest.config.js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;testEnvironment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;jsdom&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;^.+&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s1"&gt;.jsx$&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;babel-jest&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;^.+&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s1"&gt;.js$&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;babel-jest&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;setupFiles&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;rootDir&amp;gt;/jest.init.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;jest.init.js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@babel/polyfill&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This quickly allowed me to skip the docs at least for some time and move on to get stuff done.&lt;/p&gt;

&lt;h2&gt;
  
  
  #2. Testing with react-hooks-testing-library
&lt;/h2&gt;

&lt;p&gt;First I've installed &lt;a href="https://github.com/testing-library/react-testing-library" rel="noopener noreferrer"&gt;react-testing-library&lt;/a&gt;. But soon discovered another option to test react hooks — &lt;a href="https://github.com/mpeyper/react-hooks-testing-library" rel="noopener noreferrer"&gt;react-hooks-testing-library&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Usage example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;renderHook&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;act&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-hooks-testing-library&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;useCounter&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./useCounter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;should increment counter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;renderHook&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;useCounter&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="nf"&gt;act&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No additional components for wrapping up hooks manually. Neat!&lt;/p&gt;

&lt;p&gt;Other big deal about react-hook-testing-library is that it allows to handle asynchronous nature in your react hook. With a small caveat. More on that later.&lt;/p&gt;

&lt;h2&gt;
  
  
  #3. Fighting with &lt;code&gt;npm link&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;This was quite... annoying one. &lt;code&gt;npm link&lt;/code&gt; command can be used to test your package in local development without publishing it to npm registry. Sweet, convenient, did not work out of the box for me.&lt;/p&gt;

&lt;p&gt;React was throwing error about having two React instances in a same application. The reason was is some woodoo magic in npm linking.&lt;/p&gt;

&lt;p&gt;The solution was simple, ugly and necessary.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This problem can also come up when you use npm link or an equivalent. In that case, your bundler might “see” two Reacts — one in application folder and one in your library folder.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Assuming myapp and mylib are sibling folders, one possible fix is to run npm link ../myapp/node_modules/react from mylib. This should make the library use the application’s React copy.&lt;/p&gt;

&lt;p&gt;I assume it would be resolved in future versions of npm / react.&lt;/p&gt;

&lt;h2&gt;
  
  
  #4. «Better &lt;code&gt;npm publish»&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;«Better npm publish». This title stuck with me some time ago. I have never check it out but doing a quick google search revealed a &lt;a href="https://github.com/sindresorhus/np" rel="noopener noreferrer"&gt;tool called np&lt;/a&gt; to automate package publishing process.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz90d70wa3fg67rc94xms.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz90d70wa3fg67rc94xms.gif" width="800" height="292"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;package.json&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"publish"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"np"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using this tool adds some amount of safety without adding much complexity. Sweet!&lt;/p&gt;

&lt;h2&gt;
  
  
  #5. Fighting &lt;del&gt;myself&lt;/del&gt; annoying bug
&lt;/h2&gt;

&lt;p&gt;In order to be honest I need to say that this bug was a significant part of pain while writing 100 LOC. Just because of a silly bug that was successfully hiding from my attention. For an hour, or two, or...&lt;/p&gt;

&lt;p&gt;Here is a line of code with a bug:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;jsonp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yeap, that simple line of code. But &lt;code&gt;url&lt;/code&gt; was a real URL but not the one that I need. Naming is important, and so is sleeping enough.&lt;/p&gt;

&lt;h2&gt;
  
  
  #6. Fighting async nature of a react hook
&lt;/h2&gt;

&lt;p&gt;If there is some async stuff happening in your hooks you may wonder how to test. There is a simple way.&lt;/p&gt;

&lt;p&gt;Here is a part of test:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;act&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="cm"&gt;/* this one makes a http request */&lt;/span&gt;
  &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]({&lt;/span&gt;
    &lt;span class="na"&gt;EMAIL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;EMAIL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;NAME&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="cm"&gt;/* checks loading before request */&lt;/span&gt;
&lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="cm"&gt;/*
        sweet part.
        this one «waits» until there state of a hook will change.
    */&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;act&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;waitForNextUpdate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="cm"&gt;/* checks loading after request */&lt;/span&gt;
&lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But in order to follow that way I had to spend two hours realizing that I need to use alpha version of React.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;package.json&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"peerDependencies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"react"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^16.8.6"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"devDependencies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"react"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"16.9.0-alpha.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"react-dom"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"16.9.0-alpha.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"react-test-renderer"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"16.9.0-alpha.0"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;During development in order tests to work you need apha version of react. But in order to use it you can leave ^16.8.6 as a dependency.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;#7 Let's steal an API from react-apollo&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;At first my &lt;code&gt;state&lt;/code&gt; for holding data looked like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useMailchimp&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then I remembered that react had a nice API to work with requests. And what they come to was something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Query&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;GET_DOGS&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{({&lt;/span&gt; &lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="cm"&gt;/* ... */&lt;/span&gt;
    &lt;span class="p"&gt;}}&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Query&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I though it was better. API of my hook would be similar to something in the wild. And also I would not expose string variables.&lt;/p&gt;

&lt;p&gt;So I've converted an API into:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useMailchimp&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Bonus: &lt;code&gt;data&lt;/code&gt; holds an original JSON representation of an API response from MailChimp.&lt;/p&gt;

&lt;h2&gt;
  
  
  #8. I need a reset() action
&lt;/h2&gt;

&lt;p&gt;I need to decide what API my hook exposes. Using this hook by myself I realized that I do need a &lt;code&gt;reset&lt;/code&gt; functionality for hook.&lt;/p&gt;

&lt;p&gt;Done!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;subsctibe&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reset&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useMailchimp&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  #9. Zero config, many builds
&lt;/h2&gt;

&lt;p&gt;Digging into open source libs I've stumbled upon &lt;code&gt;microbundle&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The zero-configuration bundler for tiny modules, powered by Rollup.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code&gt;package.json&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"microbundle -o dist/ --sourcemap false --compress false"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Oh, that nice feeling then zero config means minimal effort from your behalf!&lt;/p&gt;

&lt;h2&gt;
  
  
  #10. Exposing your work teaches you
&lt;/h2&gt;

&lt;p&gt;Final lesson.&lt;/p&gt;

&lt;p&gt;Although tasks seems to look quite easy it steal manages to eat surprising amount of time. In that case I am trying to remember that it is partially because of me and partially because of the freaking complexity of reality. :) This mindset leaves just enough pressure on me to improve but does not make me overwhelmed or frustrated too much.&lt;/p&gt;

&lt;p&gt;As you can see you can learn a bunch of stuff by doing an open source job. Also you can skip learning some stuff which is good to keep personal momentum and make job done.&lt;/p&gt;

&lt;h1&gt;
  
  
  Open Source
&lt;/h1&gt;

&lt;p&gt;All of this is packed into &lt;a href="https://github.com/rg4real/react-use-mailchimp" rel="noopener noreferrer"&gt;react-use-mailchimp&lt;/a&gt; package we can enjoy in any of our react application.&lt;/p&gt;

&lt;p&gt;If there was any value and you want to get some more — go check out my blog. The good stuff &lt;a href="https://blog.swingpulse.com/" rel="noopener noreferrer"&gt;is waiting for you&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>opensource</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How To Add Responsive Cover Images To Gatsby Blog Posts</title>
      <dc:creator>Rohov Dmytro</dc:creator>
      <pubDate>Tue, 14 May 2019 09:14:43 +0000</pubDate>
      <link>https://dev.to/rohovdmytro/how-to-add-responsive-cover-images-to-gatsby-blog-posts-2n2m</link>
      <guid>https://dev.to/rohovdmytro/how-to-add-responsive-cover-images-to-gatsby-blog-posts-2n2m</guid>
      <description>&lt;p&gt;In this post I will describe how to add a full size image cover to your blog posts.&lt;/p&gt;

&lt;p&gt;Nice thing about Gatsby that we can handle this very nicely with plugins while not taking care about manually serving different images for different screen sizes. Each device will receive it's optimized version of the cover. Neat!&lt;/p&gt;

&lt;p&gt;This post is a part of «&lt;a href="https://blog.swingpulse.com/10x-better-gatsby" rel="noopener noreferrer"&gt;10x Better Gatsby&lt;/a&gt;» series where I share my personal experience on tuning, boosting and tweaking Gatsby. I will post more good stuff about tuning Gatsby. Check it out!&lt;/p&gt;

&lt;h3&gt;
  
  
  Assumptions
&lt;/h3&gt;

&lt;p&gt;I will assume that you've already have your markdown set up. This means that you've got this plugins being installed and configured:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;gatsby-source-filesystem&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gatsby-transformer-remark&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Instruction
&lt;/h1&gt;

&lt;h2&gt;
  
  
  #1. Editing Config
&lt;/h2&gt;

&lt;p&gt;Make sure plugins are set up in your config.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// gatsby-config.js&lt;/span&gt;
&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="cm"&gt;/*
    ...
  */&lt;/span&gt;
  &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="cm"&gt;/*
    ...
    */&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`gatsby-transformer-remark`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`gatsby-remark-images`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="na"&gt;maxWidth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;620&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="s2"&gt;`gatsby-transformer-sharp`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;`gatsby-plugin-sharp`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="cm"&gt;/*
      ...
    */&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  #2. Updating Markdown file
&lt;/h2&gt;

&lt;p&gt;Put your image near your markdown file and update your markdown file (in my case it is &lt;code&gt;post.md&lt;/code&gt;) to point &lt;code&gt;cover&lt;/code&gt; field to an image.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;How&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Failing&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;With&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Pomodoro&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Technique&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Made&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Me&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;2x&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Better&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Programmer'&lt;/span&gt;
&lt;span class="na"&gt;date&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;2019-03-27'&lt;/span&gt;
&lt;span class="na"&gt;cover&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;./cover.png'&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now lets update our GraphQL queries.&lt;/p&gt;

&lt;h2&gt;
  
  
  #3. Updating GraphQL query
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;blog-post.js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;graphql&lt;/span&gt;&lt;span class="s2"&gt;`
  query BlogPostBySlug($slug: String!) {
    markdownRemark(fields: { slug: { eq: $slug } }) {
      id
      html
      frontmatter {
        date(formatString: "MMMM DD, YYYY")
        title
        cover {
          publicURL
          childImageSharp {
            sizes(maxWidth: 2000) {
              ...GatsbyImageSharpSizes
            }
          }
        }
      }
    }
  }
`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can edit your components code.&lt;/p&gt;

&lt;h2&gt;
  
  
  #4. Updating React Component
&lt;/h2&gt;

&lt;p&gt;Make sure you have a &lt;code&gt;gatsby-image&lt;/code&gt; installed. This is a component that will handle all the responsive magic.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add gatsby-image
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In order to display image full size I am passing &lt;code&gt;cover&lt;/code&gt; data to my &lt;code&gt;Layout&lt;/code&gt; component&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Layout&lt;/span&gt;
  &lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;siteTitle&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;cover&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;frontmatter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cover&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* ... */&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Layout&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then I am displaying that data in my Layout component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Img&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;gatsby-image&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Component usage is quite simple. This is how I do it in my &lt;code&gt;Layout.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;!!&lt;/span&gt;&lt;span class="nx"&gt;cover&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Img&lt;/span&gt; &lt;span class="nx"&gt;sizes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;cover&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;childImageSharp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sizes&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&amp;gt; : nul&lt;/span&gt;&lt;span class="err"&gt;l
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  The result
&lt;/h1&gt;

&lt;p&gt;Example of a result you can get with this simple steps.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2A_XQ4NAPjbRbx1xTK8m_7gg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2A_XQ4NAPjbRbx1xTK8m_7gg.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now you can be happy with your cool looking cover that is optimized to load fast for every device.&lt;/p&gt;

&lt;p&gt;Hey! This is just one piece from «&lt;a href="https://blog.swingpulse.com/10x-better-gatsby" rel="noopener noreferrer"&gt;10x Better Gatsby&lt;/a&gt;» series. Let me share you what you will appreciate, check it out!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>gatsby</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How To Add Draft Posts to A Gatsby Blog</title>
      <dc:creator>Rohov Dmytro</dc:creator>
      <pubDate>Thu, 09 May 2019 09:25:36 +0000</pubDate>
      <link>https://dev.to/rohovdmytro/how-to-empower-a-gatsby-blog-with-draft-posts-3odd</link>
      <guid>https://dev.to/rohovdmytro/how-to-empower-a-gatsby-blog-with-draft-posts-3odd</guid>
      <description>&lt;p&gt;I need to exclude specific posts from displaying in production in my blog build with Gatsby and mark them as drafts during development. I will describe how to achieve this goal (manually or via an open sourced plugin) so you can do this too in less than 5 minutes. &lt;/p&gt;

&lt;p&gt;This post is a part of «&lt;a href="https://blog.swingpulse.com/10x-better-gatsby" rel="noopener noreferrer"&gt;10 Better with Gatsby&lt;/a&gt;» series where I share my personal experience on tuning and tweaking Gatsby. I will post more good stuff about tuning Gatsby. Check it out! &lt;/p&gt;

&lt;h1&gt;
  
  
  The End Result
&lt;/h1&gt;

&lt;p&gt;List of posts in development:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.swingpulse.com%2F%2Fstatic%2F76861222a5c825c0cd6efcd47a1a2658%2F2d6e0%2Fposts_after.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.swingpulse.com%2F%2Fstatic%2F76861222a5c825c0cd6efcd47a1a2658%2F2d6e0%2Fposts_after.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;List of posts in production:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.swingpulse.com%2F%2Fstatic%2F5c42c3fa1986e14b988e19bf6f2365ee%2F7b2ae%2Fposts_before.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.swingpulse.com%2F%2Fstatic%2F5c42c3fa1986e14b988e19bf6f2365ee%2F7b2ae%2Fposts_before.png"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Show all posts in development&lt;/li&gt;
&lt;li&gt;Hide draft posts in production&lt;/li&gt;
&lt;li&gt;Render released and draft posts differently in development&lt;/li&gt;
&lt;li&gt;Mark post as released automatically if its &lt;code&gt;date&lt;/code&gt; is after build time&lt;/li&gt;
&lt;li&gt;Mark post as released manually in &lt;code&gt;md&lt;/code&gt; files.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I found a &lt;a href="https://www.gatsbyjs.org/packages/gatsby-plugin-draft/" rel="noopener noreferrer"&gt;plugin&lt;/a&gt; but could not achieve everything I needed. Mine open sourced solution can be found here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/rg4real/gatsby-plugin-released" rel="noopener noreferrer"&gt;gatsby-plugin-released&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It allows you to add release functionality via config and skip part of this article. Also there are additional options you can use. Visit plugins README to learn more.&lt;/p&gt;

&lt;h1&gt;
  
  
  Overview
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Step #1. Adding new fields to GraphQL&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We will add a field called &lt;code&gt;released&lt;/code&gt; based on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;date&lt;/code&gt; field from markdown file&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;released&lt;/code&gt; field from markdown file&lt;/li&gt;
&lt;li&gt;&lt;code&gt;process.env.NODE_ENV&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;timezone&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;build time (a moment in time when the build happens)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also we will add a field called &lt;code&gt;releasedNotForced.&lt;/code&gt; Similar to &lt;code&gt;released&lt;/code&gt; but with &lt;code&gt;process.env.NODE_ENV&lt;/code&gt;  been ignored.&lt;/p&gt;

&lt;p&gt;This step is abstracted into &lt;a href="https://github.com/rg4real/gatsby-plugin-released" rel="noopener noreferrer"&gt;gatsby-plugin-released&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step #2. Update GraphQL queries to respect the &lt;code&gt;released&lt;/code&gt; value&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We should exclude drafts from building and displaying.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step #3. Update components to render drafts differently.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To have a nice visual distinction and feel good about it. :)&lt;/p&gt;

&lt;h1&gt;
  
  
  Execution
&lt;/h1&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Step #1. Adding new fields to GraphQL&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The goal of this step is to add fields to &lt;code&gt;node.frontmatter.fields&lt;/code&gt; to use via GraphQL. Gatsby offers a special API for this. What we need is to modify &lt;code&gt;gatsby-node.js&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;We will add two fields:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;released&lt;/code&gt; field&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;releasedNotForced&lt;/code&gt; field that act just like &lt;code&gt;released&lt;/code&gt; but ignores the &lt;code&gt;process.env.NODE_ENV&lt;/code&gt; variable.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Why adding two fields?
&lt;/h3&gt;

&lt;p&gt;Just in case you are wondering.&lt;/p&gt;

&lt;p&gt;In development mode we may want to force posts to be rendered without editing any GraphQL queries. It is done by forcing &lt;code&gt;released&lt;/code&gt;  to be &lt;code&gt;true&lt;/code&gt; based on &lt;code&gt;process.env.NODE_ENV&lt;/code&gt;. Thus in a development mode we loose the original value we may want to use in a component code to have a visual distinction between drafts and released posts.&lt;/p&gt;

&lt;p&gt;The way to preserve this is to always set the &lt;code&gt;released&lt;/code&gt; field in a markdown file. But it was so nice to have this value be calculated automatically based on &lt;code&gt;date&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That is why I've added a &lt;code&gt;releasedNotForced&lt;/code&gt; property — to preserve that value while forcing &lt;code&gt;released&lt;/code&gt; to be true.&lt;/p&gt;

&lt;p&gt;Remember, if you don't want to mess with your config just use &lt;a href="https://github.com/rg4real/gatsby-plugin-released" rel="noopener noreferrer"&gt;this plugin&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here is a function we use to calculate &lt;code&gt;releasedNotForced&lt;/code&gt; value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="c1"&gt;// gatsby-node.js&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;moment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;moment-timezone&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;fieldName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;timezone&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;frontmatter&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;frontmatter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hasOwnProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fieldName&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;frontmatter&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;fieldName&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;    

      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;frontmatter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dateNode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;moment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tz&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;frontmatter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;timezone&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dateNow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;moment&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;tz&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timezone&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;dateNow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isSameOrAfter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dateNode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then let's add &lt;code&gt;released&lt;/code&gt; and &lt;code&gt;releasedNotForced&lt;/code&gt; fields to &lt;code&gt;node.frontmatter.fields&lt;/code&gt;. What we need is to use the &lt;code&gt;onCreateNode&lt;/code&gt; function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;     &lt;span class="c1"&gt;// gatsby-node.js&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;onCreateNode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;actions&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;MD_TYPE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;MarkdownRemark&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;fieldName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;released&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;fieldNameNotForced&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;releasedNotForced&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;timezone&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;UTC&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;force&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NODE_ENV&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;development&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createNodeField&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;actions&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;fieldName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fieldNameNotForced&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;

      &lt;span class="c1"&gt;// Skip modifications for non-markdown files&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;internal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;MD_TYPE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getValue&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;

      &lt;span class="nf"&gt;createNodeField&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;fieldName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;force&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;})&lt;/span&gt;
      &lt;span class="nf"&gt;createNodeField&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;fieldNameNotForced&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Step #2. Update GraphQL queries to respect the &lt;code&gt;released&lt;/code&gt; value&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;We need to exclude drafts from a build step in file &lt;code&gt;gatsby-node.js&lt;/code&gt; and respect the &lt;code&gt;released&lt;/code&gt; value from blog pages such as &lt;code&gt;index.js.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In both cases the query will look something like this. Pay attention to a filter property.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;graphql&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s2"&gt;`
          {
            allMarkdownRemark(
              sort: { fields: [frontmatter___date], order: DESC }
              filter: { fields: { released: { eq: true } } }
            ) {
              edges {
                node {
                                id
                }
              }
            }
          }
        `&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Step #3. Update components to render drafts differently&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;This step is totally up to yours component tree. The key point is to request necessary fields via GraphQL query.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;graphql&lt;/span&gt;&lt;span class="s2"&gt;`
      query {
        allMarkdownRemark(
          sort: { fields: [frontmatter___date], order: DESC }
          filter: { fields: { released: { eq: true } } }
        ) {
          edges {
            node {
              id
              fields {
                slug
            released
            releasedNotForced
              }
            }
          }
        }
      }
    `&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;So we have a single GraphQL query for production and development, &lt;code&gt;released&lt;/code&gt; field is calculated automatically and draft posts can be rendered differently. Cool!&lt;/p&gt;

&lt;p&gt;And be warned! There are drafts in my «&lt;a href="https://blog.swingpulse.com/10x-better-gatsby" rel="noopener noreferrer"&gt;10x better Gatsby&lt;/a&gt;» series! :) So go check it out to stay tuned!&lt;/p&gt;

</description>
      <category>gatsby</category>
      <category>react</category>
      <category>tutorial</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
