<?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: Alex Edwards</title>
    <description>The latest articles on DEV Community by Alex Edwards (@_lexedwards).</description>
    <link>https://dev.to/_lexedwards</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%2F254539%2Ff3d21051-8257-4cbf-be34-9f14f5d83900.png</url>
      <title>DEV Community: Alex Edwards</title>
      <link>https://dev.to/_lexedwards</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/_lexedwards"/>
    <language>en</language>
    <item>
      <title>Where to go from here?</title>
      <dc:creator>Alex Edwards</dc:creator>
      <pubDate>Thu, 30 Jul 2020 10:10:30 +0000</pubDate>
      <link>https://dev.to/_lexedwards/where-to-go-from-here-3j92</link>
      <guid>https://dev.to/_lexedwards/where-to-go-from-here-3j92</guid>
      <description>&lt;p&gt;There are plenty of roadmaps out there if you simply google 'developer roadmap', but I also value the personal details and I'm in need of a bit of a review.&lt;/p&gt;

&lt;p&gt;In the last few months of 2019, I quit my job, moved in with my folks to focus on learning Full-stack JS development, fell in love with Front-end, but really enjoy the puzzle-solving aspect to Back-end work. I've even started to enjoy writing tests.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Thanks to Kent C Dodds &lt;a href="//testingjavascript.com/"&gt;Testing-Javascript&lt;/a&gt; course! Highly recommend it for anyone who's looking to incorporate or learn it's value&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I learnt React previous to the introduction to hooks, then I learnt it over again.&lt;/p&gt;

&lt;p&gt;Since March 2020 when the lock-down hit the UK hard, there's been about 1% of the jobs going, most are senior / lead roles, and so as someone who's looking for their first 'real' role (I've dabbled here and there with paid work in the past).&lt;/p&gt;

&lt;p&gt;So after some advice, to get Job-ready when they start coming back into the market, I've been learning Typescript (I ❤️ it!), Data Structures and Algorithms, GraphQL back-end (Found &lt;a href="//nexusjs.org/"&gt;Nexus&lt;/a&gt; from Prisma and it's SO easy to work with!). Built a website in June with Gatsby, TS, and a CMS. Finished another &lt;a href="https://dev.to/_lexedwards/got-stuck-in-a-hole-ended-up-revisiting-a-previous-project-accessibility-colour-palettes-12p3"&gt;project&lt;/a&gt; yesterday.&lt;/p&gt;

&lt;p&gt;I'm not sure where else to go from here, should I continue building more projects, even if they're a bit copy-pasta using sites like [Frontend Mentor)(&lt;a href="https://www.frontendmentor.io/"&gt;https://www.frontendmentor.io/&lt;/a&gt;) for visual queues? I have this bias that projects from courses are viewed a bit this way too - everyone producing the same project with minor differences.&lt;/p&gt;

&lt;p&gt;I've learnt React, but is there value in learning Vue too? Vue3 is around the corner though not ready, I'm seeing it as a frequent feature in jobs advertised.&lt;/p&gt;

&lt;p&gt;As Full-stack too, would I be wrong to invest in learning Python? Also tempted by IOS.&lt;/p&gt;

&lt;p&gt;I'm constantly wanting to improve and thrive to do better, but as someone who values their time, I'm not wanting to go down the wrong direction or waste time, especially when the end goal is to get their first placement in a team and contribute to something more than just personal exhibition.&lt;/p&gt;

</description>
      <category>help</category>
      <category>career</category>
    </item>
    <item>
      <title>Got stuck in a hole, ended up revisiting a previous project - Accessibility Colour Palettes</title>
      <dc:creator>Alex Edwards</dc:creator>
      <pubDate>Thu, 30 Jul 2020 09:45:19 +0000</pubDate>
      <link>https://dev.to/_lexedwards/got-stuck-in-a-hole-ended-up-revisiting-a-previous-project-accessibility-colour-palettes-12p3</link>
      <guid>https://dev.to/_lexedwards/got-stuck-in-a-hole-ended-up-revisiting-a-previous-project-accessibility-colour-palettes-12p3</guid>
      <description>&lt;p&gt;It's coming up to nearly a year now since I took a leap to quit my full-time job (having gotten savings in place) and focus on learning development and get into my first job. I figured 2020 would be a start on a very long road to a serious outlook to this career (where I had only dabbled previously, with projects, and sporadic  paid work.&lt;/p&gt;




&lt;p&gt;Well, we all know what's happened to 2020, and the job market in the UK has all but dried up; advertised jobs have gone to about less than 1% of what it was before Covid.&lt;/p&gt;

&lt;p&gt;So back in March, I've gotten some serious advice to get going on learning, certifications, projects etc. and be job-ready and skilled once recovery starts taking place. I've been learning Data-Structures &amp;amp; Algorithms, Typescript, GraphQL back-end, etc. I'm still pretty flaky with designing, but I'm getting there.&lt;/p&gt;

&lt;p&gt;All of this while battling a somewhat depression ( us Brits are notorious for downplaying mental health, but in times like these, you've got to acknowledge it at least. I mean, I just quit an almost sure thing, personal-life stuff etc.)&lt;/p&gt;

&lt;p&gt;Last month I built my own website using Typescript, React ( GatsbyJs ) and a GraphQL CMS. In the past two weeks I revisited an older project that I never completed and vastly improved it's functionality while not once referencing the old material.&lt;/p&gt;




&lt;p&gt;My &lt;a href="https://github.com/lexedwards/Color-Contrast"&gt;Color Contrast App&lt;/a&gt; is based on the idea of allowing you to pick your own colors, branding etc. but then being able to plug it into this react app to ensure that the colors align with one-another across the board. This way whether it's light/dark mode or even a multitude of different themes on the site, you know that each color's shade is the same and interchangeable. &lt;/p&gt;

&lt;p&gt;I.e. &lt;code&gt;red-100&lt;/code&gt; has the same contrast to white as &lt;code&gt;blue-100&lt;/code&gt;, &lt;code&gt;green-100&lt;/code&gt;, etc.&lt;/p&gt;

&lt;p&gt;This is important as Hex/Rgb is hard to read for contrast, and HSL's &lt;em&gt;L&lt;/em&gt; value isn't a good value for contrast as greens are much lighter and blues are much darker regardless of the L value.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;The Repo&lt;/strong&gt;: &lt;a href="https://github.com/lexedwards/Color-Contrast"&gt;github&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;The Live demo&lt;/strong&gt;: &lt;a href="https://heuristic-bose-979cbd.netlify.app/"&gt;Netlify&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;The Todos:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Design a mobile friendly version (Though, this is an edge case)&lt;/li&gt;
&lt;li&gt;Implement Server-Side State with login credentials&lt;/li&gt;
&lt;li&gt;Long-press on editor fields&lt;/li&gt;
&lt;li&gt;Create download file / Copy CSS Custom Variables from State&lt;/li&gt;
&lt;li&gt;Better Tests (I'm still new to testing everything, but I'm getting better)&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;What I'm stuck on:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I'm not sure the best way is to be able to dynamically create a downloadable file based on state. It's just a text file with a &lt;code&gt;.sketchpalette&lt;/code&gt; file extension that will work with the &lt;a href="https://github.com/andrewfiorillo/sketch-palettes"&gt;Sketch Palette&lt;/a&gt; plugin.&lt;/p&gt;

&lt;p&gt;Similarly, to be able to copy the state as CSS Custom Variables I've read somewhere I would need to populate a &lt;code&gt;textfield&lt;/code&gt; with the state output, and copy from that rather than directly from a function?&lt;/p&gt;

&lt;p&gt;I'm still new to testing, having only really worked on my website with tests and then this one too. I'm at about 95% coverage which I'm happy about as it covers as the User would interact rather than implementation, however, if anyone can point out major potholes I've missed, please, let me know! I'd love to be able to improve!&lt;/p&gt;

&lt;p&gt;Other than that, if you have any comments on the project and other feedback, please, let me know! I'm kind of working in a bubble right now and explaining these projects to a non-tech family member, or a 5-month old puppy can be a bit one-way.&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>help</category>
      <category>react</category>
    </item>
    <item>
      <title>Parsing Markdown from a CMS</title>
      <dc:creator>Alex Edwards</dc:creator>
      <pubDate>Thu, 18 Jun 2020 19:57:48 +0000</pubDate>
      <link>https://dev.to/_lexedwards/parsing-markdown-from-a-cms-ad</link>
      <guid>https://dev.to/_lexedwards/parsing-markdown-from-a-cms-ad</guid>
      <description>&lt;p&gt;Parsing is a heavy topic, so this post is a bit code heavy, however, I'll try my best to explain away.&lt;/p&gt;

&lt;p&gt;I'll save some time here; I spend 1/2 a day invested in getting MDX working with Contentful; I couldn't get it to work.&lt;/p&gt;

&lt;p&gt;Instead, I figured after a moment, with Remark-Rehype, I can kill two birds with one stone. I can get Markdown to work, that covers 90% of my use case, and when I need another component rendering, adding custom components when required.&lt;/p&gt;

&lt;p&gt;Rehype-React is the package that takes in trusted &lt;code&gt;HAST&lt;/code&gt; and responds with react components rendered. HAST, as I had to learn, is an acronym for HTML abstract syntax tree. It breaks down HTML into an object that contains arrays of other objects containing properties and children. &lt;br&gt;
Sounds complicated, huh?&lt;/p&gt;

&lt;p&gt;Don't need to worry about it until tempted to write a plugin. Until that moment; &lt;strong&gt;this&lt;/strong&gt; is the moment to change how that HAST turns into rendered code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;renderAst&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;rehypeReact&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;Fragment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Fragment&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;components&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Heading&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;H1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Heading&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;H2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;h3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Heading&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;H3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;h4&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Heading&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;H4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;h5&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Heading&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;H5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;h6&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Heading&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;H6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;p&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;P&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Link&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;ol&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;OL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;UL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;li&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;LI&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;blockquote&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;BQ&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;table&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Table&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;th&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;TH&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;td&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;TD&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;hr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;HR&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="nx"&gt;Compiler&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;What's to be understood here is that unlike the Gatsby plugin for Rehype-React, this allows the given HAST to have custom components rendering its content. Passing our Contentful HAST into &lt;code&gt;renderAst()&lt;/code&gt; we can ensure that each HTML heading, paragraph, and anything else follows suit with the rest of the site. That even includes anchor links that can and will take full advantage of Gatbsy's Link component. &lt;/p&gt;

&lt;h2&gt;
  
  
  Custom Link logic
&lt;/h2&gt;

&lt;p&gt;To do that, we need to implement our component. I know, sounds counter-intuitive. However, if done correctly, we can drop in a different import and done.&lt;/p&gt;

&lt;p&gt;First, we need to check the &lt;code&gt;to&lt;/code&gt; or &lt;code&gt;href&lt;/code&gt; attribute. Why? Because in our code, we'll pass in the &lt;code&gt;to&lt;/code&gt; argument, however, our HAST will pass in &lt;code&gt;href&lt;/code&gt;. Everything else will be down to what we give to them, or any additional parameters—aspects such as &lt;code&gt;activeClass&lt;/code&gt;. All other logic will come from regex passed to the link.&lt;/p&gt;

&lt;p&gt;First, let's see if it's an internal link by matching it with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;internal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/^&lt;/span&gt;&lt;span class="se"&gt;\/(?!\/)&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This regex looks to the front of the string for &lt;code&gt;/&lt;/code&gt;, but &lt;strong&gt;not&lt;/strong&gt; &lt;code&gt;//&lt;/code&gt;.&lt;br&gt;
If it's an internal link, it count be a download. So let's match it the response with looking to the end of the string. That's relatively straight forward too; the line starts with &lt;code&gt;/&lt;/code&gt; and ends with '.(something), in regex that translates to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\.[&lt;/span&gt;&lt;span class="sr"&gt;0-9a-z&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;+$/i&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;$&lt;/code&gt; is for the end of the string, and the &lt;code&gt;+&lt;/code&gt; is to any combination of 0-9, a-z, in any amount.&lt;/p&gt;

&lt;p&gt;The other difficult one would be a local navigation link. That's something that begins with a &lt;code&gt;#&lt;/code&gt; or &lt;code&gt;?&lt;/code&gt;. It's difficult only for that it doesn't start with a &lt;code&gt;/&lt;/code&gt; and won't work for accessibility if we pass in an 'onClick' prop.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;local&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/^&lt;/span&gt;&lt;span class="se"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;#?&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;If none of that matches, then as a fail, return a bog-standard, standard anchor link that fulfils all accessibility and security concerns. All of it combined looks something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight tsx"&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;Link&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;GLink&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;gatsby&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Link&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;activeClassName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;partiallyActive&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;rest&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;LinkComponent&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ReactElement&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;internal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/^&lt;/span&gt;&lt;span class="se"&gt;\/(?!\/)&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\.[&lt;/span&gt;&lt;span class="sr"&gt;0-9a-z&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;+$/i&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;local&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/^&lt;/span&gt;&lt;span class="se"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;#?&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;href&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;ref&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;rest&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;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;internal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;download&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;rest&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;GLink&lt;/span&gt; &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;ref&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/`&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;activeClassName&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;activeClassName&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;partiallyActive&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;partiallyActive&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;rest&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;GLink&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;rest&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;)&lt;/span&gt;
  &lt;span class="c1"&gt;// All else, this is an external link&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"_blank"&lt;/span&gt; &lt;span class="na"&gt;rel&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"noreferrer"&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;rest&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Back to Rehype
&lt;/h2&gt;

&lt;p&gt;We are dropping in this logic to Rehype so that within Markdown, we can link to pages, downloads, local anchors, external sites, and everything will work as expected. So far, everything else is purely stylistic (using styled-components). However, this option that Rehype exposes is key to quickly and easily integrating stylistic choices and translating Markdown into react components.&lt;/p&gt;

&lt;p&gt;To fully utilise rehype, we now parse the HtmlAst field from any long-field text:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Homepage&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="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;contentfulPage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&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="n"&gt;regex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/homepage/i"&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="n"&gt;title&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;blocks&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;on&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ContentfulPageHome&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="n"&gt;title&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;subTitle&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;authorBio&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="n"&gt;blurbTitle&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="n"&gt;blurbDesc&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="n"&gt;childMarkdownRemark&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="n"&gt;htmlAst&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="n"&gt;blurbLead&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;renderAst&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;blocks&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;authorBio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;blurbDesc&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;childMarkdownRemark&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;htmlAst&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Using &lt;code&gt;renderAst()&lt;/code&gt; keeps components, pages, and templates clean as there aren't any further imports needed than our function, and generated code, writing integration tests or end-to-end tests ensure the output plays well with the code we write. Using styled-components can keep everything aligned when themes change, typography adjusts, and later in other components.&lt;/p&gt;

&lt;p&gt;The last thing to address is images.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gatsby Image with Contentful API
&lt;/h2&gt;

&lt;p&gt;Thankfully someone, just like sourcing from Contentful, has already created a plugin for this. &lt;code&gt;gatsby-remark-images-contentful&lt;/code&gt; will pull in any asset &lt;strong&gt;hosted on Contentful&lt;/strong&gt; and allow &lt;a href="https://github.com/lovell/sharp"&gt;Sharp&lt;/a&gt; to process images into fixed or fluid types to be used by gatsby-image. Under the hood, it works in a similar way to how querying an image would normally. Something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="err"&gt;profilePicture&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="n"&gt;fluid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;maxWidth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;260&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="n"&gt;GatsbyContentfulFluid_tracedSVG&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;div class="highlight"&gt;&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Img&lt;/span&gt; &lt;span class="na"&gt;fluid&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;blocks&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;authorBio&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;profilePicture&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;fluid&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Only images hosted on Contentful itself will be processed by &lt;code&gt;images-contentful&lt;/code&gt;. Remark and Rehype will parse 3rd-Party hosts into standard image nodes.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code&gt;Gatsby-Remark-Images&lt;/code&gt; is another option; however, at the time of writing this, installing alongside or installing instead of &lt;code&gt;images-contentful&lt;/code&gt; causes problems. Namely doesn't accurately process the images from Contentful at all. Since I'm already utilising Contentful, I'm doubling down on image handling.&lt;/p&gt;




&lt;p&gt;This post is an ongoing series along with my site development. All current process on my &lt;a href="https://alexedwards.co"&gt;website&lt;/a&gt; and in the &lt;a href="https://github.com/lexedwards/alexedwards-co"&gt;open-source repo&lt;/a&gt; is open for review. As I publish new features (Posts and Projects templates, changes in style), I'll continue to add to this series as a reflection of what I've learnt, and what reflections I have on the process.&lt;/p&gt;

</description>
      <category>gatsby</category>
      <category>graphql</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Rendering a Page</title>
      <dc:creator>Alex Edwards</dc:creator>
      <pubDate>Sat, 13 Jun 2020 15:19:45 +0000</pubDate>
      <link>https://dev.to/_lexedwards/rendering-a-page-4bmo</link>
      <guid>https://dev.to/_lexedwards/rendering-a-page-4bmo</guid>
      <description>&lt;p&gt;In &lt;a href="https://dev.to/_lexedwards/writing-the-first-test-component-5h1o"&gt;Part II&lt;/a&gt; I covered the prototyping and implementation of writing components, today I'm going to cover how to create Pages from Contentful.&lt;/p&gt;

&lt;p&gt;For this, I had to learn precisely how Contentful manages its database-style CMS, how the source plugin pulls information, and how base to utilise it.&lt;/p&gt;

&lt;p&gt;My thoughts behind the difference between Page and Template are quite simple:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A Page&lt;/strong&gt; is purpose-built and has no ambiguity to what is displayed. Meaning a unique &lt;a href="https://www.contentful.com/developers/docs/concepts/data-model/"&gt;content-model&lt;/a&gt; for each and every page. &lt;strong&gt;A Template&lt;/strong&gt; however, has to be generalised by design. A Template for my posts may include many different elements, components even, but I'll get onto that later. Likewise, some fields might be optional, but the key aspects need to be assured requirements. That might include elements such as a unique slug, or a publish date modifiable by the user.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Model
&lt;/h2&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/c6pc38xsagw4/1Yxiio6iGAmF3Dh7eQIGB4/b6dc550eb55a11431d4712e4db357ed4/Screen_Shot_2020-06-12_at_15.32.20.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/c6pc38xsagw4/1Yxiio6iGAmF3Dh7eQIGB4/b6dc550eb55a11431d4712e4db357ed4/Screen_Shot_2020-06-12_at_15.32.20.png" alt="Screenshot of a Page Content Model"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;'Top Level Page?' and Index came around because of a need in the code rather than instinct. Contentful generates its Indexes with UUID on every field; however, if it's a top-level page (think like a site map), then you would want to give it an index of importance.&lt;/p&gt;

&lt;p&gt;The other two exciting fields are Meta and Blocks. Meta is another content model that exists globally. Ensuring that all content has the right information, and unique where needed, making sure things like publishing dates are correct, and slugs don't override each other.&lt;/p&gt;

&lt;p&gt;Page Blocks are the unique aspect for every page. A new content model needed for every page.&lt;/p&gt;

&lt;p&gt;&lt;a href="//images.ctfassets.net/c6pc38xsagw4/6vXxwEHf4yKOltiHJ9HOKz/c2d74c0a65016c1b58c4c40cfeff0c41/Screen_Shot_2020-06-12_at_15.45.27.png" class="article-body-image-wrapper"&gt;&lt;img src="//images.ctfassets.net/c6pc38xsagw4/6vXxwEHf4yKOltiHJ9HOKz/c2d74c0a65016c1b58c4c40cfeff0c41/Screen_Shot_2020-06-12_at_15.45.27.png" alt="Homepage Content Model Block"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My homepage needs nothing more than a greeting, subtext and a little about myself, which I'll include in my Author Bio; which in turn also houses all my social links and ways to contact me. &lt;/p&gt;

&lt;p&gt;Okay, so now the content model is established.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Code
&lt;/h2&gt;

&lt;p&gt;Removing all the trailing curly-brackets, this is what I'm querying for:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Homepage&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="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;contentfulPage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&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="n"&gt;regex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/homepage/i"&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="n"&gt;title&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;blocks&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;on&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ContentfulPageHome&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="n"&gt;title&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;subTitle&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;authorBio&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="n"&gt;blurbTitle&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="n"&gt;blurbDesc&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="n"&gt;blurbDesc&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="n"&gt;blurbLead&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;For simplicity, I've removed some styling choices, but this is what it rendered as in my TSX file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PageHome&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;IndexPage&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="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="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;blocks&lt;/span&gt; &lt;span class="o"&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;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;blocks&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;subBlack&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;blocks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subTitle&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;slice&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="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;subColor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;blocks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subTitle&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;blocks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;✌️&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h5&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;subBlack&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;subColor&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h5&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;img&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;blocks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;authorBio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;blurbTitle&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;blocks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;authorBio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;blurbDesc&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;&lt;span class="nx"&gt;blurbDesc&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Components with page queries necessarily have two elements to the file, the query variable, then the functional component that Gatsby passes the query into, via the &lt;code&gt;data&lt;/code&gt; prop. Using Typescript, that data has an interface; otherwise, the TS Compiler will throw a hissy-fit. Typescript can get extensive, yet gives you complete confidence what elements are present, optional, and otherwise.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;PageHome&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Page&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;blocks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HomeBlocks&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;HomeBlocks&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
  &lt;span class="nx"&gt;subTitle&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
  &lt;span class="nx"&gt;authorBio&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Bio&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Some bits are missing here, such as the &lt;code&gt;Page&lt;/code&gt; &amp;amp; &lt;code&gt;Bio&lt;/code&gt; interfaces. However, each unique 'block' takes the original 'Page' with all the common elements and adds additional types where needed. Per the content model, subTitle hasn't deemed it as a requirement, so both interface and component need to cover that.&lt;/p&gt;

&lt;p&gt;The next step is tricky, so I'll be covering that in its post; How I implemented rendering assistants to display typography, hyperlinks, and images into the code.&lt;/p&gt;




&lt;p&gt;This post is an ongoing series along with my site development. All current process on my &lt;a href="https://alexedwards.co"&gt;website&lt;/a&gt; and in the &lt;a href="https://github.com/lexedwards/alexedwards-co"&gt;open-source repo&lt;/a&gt; is open for review. As I publish new features (Posts and Projects templates, changes in style), I'll continue to add to this series as a reflection of what I've learnt, and what reflections I have on the process.&lt;/p&gt;

</description>
      <category>gatsby</category>
      <category>testing</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Writing the First Test &amp; Component</title>
      <dc:creator>Alex Edwards</dc:creator>
      <pubDate>Fri, 12 Jun 2020 16:00:21 +0000</pubDate>
      <link>https://dev.to/_lexedwards/writing-the-first-test-component-5h1o</link>
      <guid>https://dev.to/_lexedwards/writing-the-first-test-component-5h1o</guid>
      <description>&lt;p&gt;Now that Typescript, Jest, and Cypress are set up and ready to go, let's run the site:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run setup
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;With the single command, npm installs everything runs the validate script which runs both Jest and Cypress one after another.&lt;/p&gt;

&lt;p&gt;Nothing should happen at this stage, as there are no tests written. From a Test-Driven perspective, tests establish both how to interact with the module and what the outcome will be. Typescript is excellent for that documentation during development, but it won't do anything for runtime.&lt;/p&gt;

&lt;p&gt;My site's going to feature a layout component that will wrap the site so that through page-change, elements in &lt;code&gt;layout&lt;/code&gt; won't flicker or repaint.  In my layout, there are SEO components; thank's to &lt;code&gt;react-helmet&lt;/code&gt;, as well as a &lt;code&gt;Header,&lt;/code&gt; and &lt;code&gt;Footer&lt;/code&gt; component. &lt;/p&gt;

&lt;p&gt;My Header will render with a &lt;code&gt;title&lt;/code&gt;, and the main navigation for the website. That information will be passed in by Gatsby's &lt;code&gt;graphql&lt;/code&gt; during Build time; so I know I need to mock the data passed into the component.  Another aspect that would be useful to know is the current location path so that any styles are adjusted to show the current page. &lt;/p&gt;

&lt;h2&gt;
  
  
  Mocking Graphql with Jest .spyOn
&lt;/h2&gt;

&lt;p&gt;Per gatsby's excellent documentation, it's as easy as statically declaring what information is present. GraphiQL is your friend here, as the data passed will be well structured and fields populated with the correct types. It will end up looking something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;useStaticQuery&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;spyOn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Gatsby&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;useStaticQuery&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;useStaticQuery&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mockImplementation&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="na"&gt;contentfulSiteMetadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello-Title&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;allContentfulPage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;edges&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;node&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;about&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;meta&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;about&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;node&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;contact&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;meta&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;contact&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;By doing this, I don't need to worry about dependency injection. Instead, Jest will monitor the component, and use its mock data for &lt;code&gt;useStaticQuery&lt;/code&gt;. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Queries and other APIs return generated data, so mock the returned value but not the implementation. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Ensure required elements are present
&lt;/h2&gt;

&lt;p&gt;So writing the tests are now as easy as ensuring that the purpose of the &lt;code&gt;Header&lt;/code&gt; component renders the right stuff:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&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;It has a CTA&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;getByRole&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;render&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;Header&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;mockLocation&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt; &lt;span class="sr"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;)
&lt;/span&gt;  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getByRole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toContain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/contact/i&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;or the better way of doing things:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&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;It has a CTA Button&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="nx"&gt;render&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;Header&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;mockLocation&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt; &lt;span class="sr"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;)
&lt;/span&gt;  &lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getByRole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button&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;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/contact/i&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;Kent C Dodds' Pro Testing-Javascript course taught the method of testing how it's interacted with rather than it's implementation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Writing the Component
&lt;/h2&gt;

&lt;p&gt;Now that I've written the test, using it as a blueprint, we can get going with the component to make the test pass. In this case, laid out to use &lt;code&gt;useStaticQuery&lt;/code&gt; and return a header element with a title present, a navigation element with links and a Call-To-Action button.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Header&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;header&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;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Alex&lt;/span&gt; &lt;span class="nx"&gt;Edwards&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;description&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;/p&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;nav&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;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;allContentfulPage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;edges&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;page&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;title&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="s2"&gt;`contact`&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;button&lt;/span&gt; 
          &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;page&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;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;page&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;meta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slug&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;page&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;title&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;/button&amp;gt;  &lt;/span&gt;&lt;span class="err"&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/nav&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;/header&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;p&gt;Rerunning the test will pass this time because our component is returning the required elements. Now it's safe to add, modify, or refactor the code and keep Jest in watch mode to ensure all changes don't affect the requirements of this module.&lt;/p&gt;

&lt;p&gt;Awesome tests to include would be using Jest-Axe to ensure all a11y requirements are passing, as well as Jest-In-Case to test through multiple props or data-values to ensure that different use cases return the right values, including error handling.&lt;/p&gt;

&lt;p&gt;Other modules, such as my footer and other singular components, have similar tests associated with them. Elements like my Layout wrapper will have a different approach, called &lt;code&gt;integration tests&lt;/code&gt;. The mentality is to ensure that everything works well together.  Does the data passed from &lt;code&gt;Layout&lt;/code&gt; to &lt;code&gt;Header&lt;/code&gt; and &lt;code&gt;Footer&lt;/code&gt; render successfully? &lt;/p&gt;

&lt;p&gt;Later, the confidence gained from these tests will allow quicker development for pages, templates and the rest.&lt;/p&gt;




&lt;p&gt;This post is an ongoing series along with my site development. All current process on my &lt;a href="https://alexedwards.co"&gt;website&lt;/a&gt; and in the &lt;a href="https://github.com/lexedwards/alexedwards-co"&gt;open-source repo&lt;/a&gt; is open for review. As I publish new features (Posts and Projects templates, changes in style), I'll continue to add to this series as a reflection of what I've learnt, and what reflections I have on the process.&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>gatsby</category>
      <category>testing</category>
    </item>
    <item>
      <title>Creating my JAM-stack site</title>
      <dc:creator>Alex Edwards</dc:creator>
      <pubDate>Sat, 06 Jun 2020 15:51:19 +0000</pubDate>
      <link>https://dev.to/_lexedwards/creating-my-jam-stack-site-33h6</link>
      <guid>https://dev.to/_lexedwards/creating-my-jam-stack-site-33h6</guid>
      <description>&lt;p&gt;*&lt;em&gt;Cover Picture by &lt;a href="https://unsplash.com/@dtravisphd"&gt;David Trivis&lt;/a&gt; on Unsplash&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;For the past two weeks, I've neglected to contribute to Dev because I've been hard at work trying to combine the tools I've learnt over the past month or two: Typescript, and Test-Driven-Development.&lt;/p&gt;

&lt;p&gt;Since arriving back in the UK in September, I've been studying React, and it's various stacks ready to transition into a front end development job, and since Covid-19 landed early this year, I've been studying more and more. However, what's the point in studying if you don't put it to practice!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Project Description&lt;/li&gt;
&lt;li&gt;The Setup&lt;/li&gt;
&lt;li&gt;The Content&lt;/li&gt;
&lt;li&gt;A TDD Story&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The Project Description:  &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Create a JAM-stack website utilising GatsbyJS (React), Typescript, and a CMS such as NetlifyCMS or ContentfulCMS.&lt;/p&gt;

&lt;p&gt;Why Gatsby? Well, React is excellent, but with SPA (Single Page Applications), SEO and page speed can be a caveat. The way Gatsby overcomes this is to create static pages and then loads React in afterwards. That way, pages load quickly and accurately, and you still gain the advantages of a SPA.&lt;/p&gt;

&lt;p&gt;Why a CMS? With Gatsby's incremental builds in Beta on Netlify, it can drastically increase build times for sites that have a lot of pages to render.&lt;/p&gt;

&lt;p&gt;Typescript and TDD are the two aspects I've learnt recently, and that was the primary practice for the project. I've learnt to embrace Typescript with open arms; however, working with libraries can be difficult if they don't have Type declaration or feature it in their documents. It's mostly mitigated these days with the DefinitelyTyped project. And with TDD the idea is that you write tests (that initially fail) as a blueprint of the code, and later write code that fits within passing the tests. This way, you're not testing implementation, but you're testing how that particular function, class, or component will interact.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Setup:  &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;gatsby new new-starter https://github.com/lexedwards/starter-cypr-jest-ts
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This starter was something of a bi-product of working with Gatsby. Once all the environment variables were in place, I saved it in another repo to use time and time again. It has Jest, Cypress, and Typescript fully supported, nothing more, nothing less. Since Gatsby uses a lot of configs under the hood, I imported my configs and tweaked them to get everything working together nicely. Partly workflow (Husky for Git hooks etc.) and somewhat getting Jest and Cypress working correctly together (Instrumentation injection for Cypress Code-Coverage)&lt;/p&gt;

&lt;h2&gt;
  
  
  The Content:  &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;First hearing about Incremental Builds from Gatsby Cloud, later reading about it from a Netlify email, in beta. However, it's a significant change as with SSG (Static Site Generators) the major complaint is how slow build time can be. Hugo has gained massive momentum for how quick it's build time is. As of this time, only a  handle of CMS' are supported, and that's what pushed me to use Contentful, including the option of writing markdown files within the Repo and importing them using Gatbsy. &lt;/p&gt;

&lt;p&gt;Developer friendly, but with one pitfall, I couldn't quite get the Gatsby Contentful plugin to play nice with MDX. So, instead, I'm using Markdown with Remark-Rehype to convert to React Components rather than pure HTML. This way, if I wanted a component in my markdown, I would be able to write:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;my-custom-component&amp;gt;&amp;lt;/my-custom-component&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;It's slightly different, however, having spent a day experimenting with Contentful and MDX with no avail, it's better than nothing.&lt;/p&gt;

&lt;p&gt;One thing to note: With the Markdown on a CMS, there's no tie to what are valid components and so manual checking on the CMS would still be required. Rich-text might be an option here, but it's processing would be done by Contentful rather than Remark.&lt;/p&gt;

&lt;h2&gt;
  
  
  A TDD story: &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;It's all fun and games following tutorials, some of which I've followed in different forms, but first starting I had to remind myself so much to write tests first! It was a bit of a grind, to begin with, metaphorically slapping my wrists for diving into new components, however, a week later, writing unit tests was a dream for development as I was setting the behaviour and expectation before even thinking about tackling the problem. I'm still slightly nieve to how best to write tests, but the more I do it, the more I understand what's gaining better confidence.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Errrrrrr, I'm not too sure&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;container&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;render&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;Component&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;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;ToBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;I don&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt; &lt;span class="nx"&gt;know&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;that&lt;/span&gt; &lt;span class="nx"&gt;it&lt;/span&gt; &lt;span class="nx"&gt;exists&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;)
})
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Kent C Dodds' course was great for this, as this is my project, I've set the standard that my coverage of tests is allowed to be less than 100%. Testing Templates and Pages pool from components are End-To-End. Testing components as interacted with rather than implemented. Functions also, I don't need to know the function is adding &lt;code&gt;1 + 1&lt;/code&gt; in a particular way, just that the result is deterministic and always equal &lt;code&gt;2&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Navigate the Default Pages&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="nx"&gt;beforeEach&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;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;visit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;injectAxe&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;

  &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Has no A11y Violations&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="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;checkA11y&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="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;runOnly&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tag&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;values&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;wcag2a&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;

  &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Has Navigation&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="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;findByRole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;navigation&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;findByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/about/i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;click&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;findByRole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;navigation&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;findByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/say hello/i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;click&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;findAllByRole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;heading&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;findByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/alex edwards/i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;click&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;*&lt;em&gt;Test taken from my E2E test on my Index page&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;This post is an ongoing series along with my site development. All current process on my &lt;a href="https://alexedwards.co"&gt;website&lt;/a&gt; and in the &lt;a href="https://github.com/lexedwards/alexedwards-co"&gt;open-source repo&lt;/a&gt; is open for review. As I publish new features (Posts and Projects templates, changes in style), I'll continue to add to this series as a reflection of what I've learnt, and what reflections I have on the process.&lt;/p&gt;

</description>
      <category>testing</category>
      <category>typescript</category>
      <category>gatsby</category>
    </item>
    <item>
      <title>Rubber Duck Debugging My Git Flow</title>
      <dc:creator>Alex Edwards</dc:creator>
      <pubDate>Mon, 18 May 2020 20:24:25 +0000</pubDate>
      <link>https://dev.to/_lexedwards/rubber-duck-debugging-my-git-flow-1kff</link>
      <guid>https://dev.to/_lexedwards/rubber-duck-debugging-my-git-flow-1kff</guid>
      <description>&lt;p&gt;My head is 🤯 after investing the previous week in &lt;a href="http://testingjavascript.com"&gt;Kent C Dodd's Testing Javascript course&lt;/a&gt; (Very much worth the effort if you ever feel in doubt about testing confidence)&lt;/p&gt;

&lt;p&gt;Today I took a step back and started looking at how I approach my projects, and my git commits in previous projects are an abstraction of that approach, where I would tackle big picture things in a single commit.&lt;/p&gt;

&lt;p&gt;After having the boat-load of information absorbed, I needed a tangent to recuperate, and so I started thinking about the redo on my website that I'm going to tackle. I ended up getting distracted for a day on a &lt;a href="https://github.com/lexedwards/starter-cypr-jest-ts"&gt;Gatsby starter&lt;/a&gt; with some testing utilities like Typescript, Jest, and Cypress - that's for another day. For let's say the combination of the three led to some different configs (Looking at you Gatsby + Jest!) and type declarations (Jest &amp;amp; Cypress).&lt;/p&gt;

&lt;p&gt;So today I got looking at how to integrate a TDD paradigm into my workflow, and as I've said, I typically look at my Git Commits for that. I used to be a sucker for directly injecting to my &lt;code&gt;master&lt;/code&gt; branch 😅. However, I now know better.&lt;/p&gt;

&lt;p&gt;So after a bit of digging into best practices and working with writing tests first, then code that will pass those tests; I present my rubber ducked flow. I call it that, because this is me, trying to explain git, TDD, and whatever else to the community while trying to solve my problem and coming up with the solution doing so. &lt;/p&gt;

&lt;p&gt;So let's step through it;&lt;/p&gt;

&lt;h2&gt;
  
  
  GIT
&lt;/h2&gt;

&lt;p&gt;Git is, in effect, a command-line based way to retain a different version of files. It can be run locally and sent to a &lt;code&gt;remote&lt;/code&gt; repository like Github, Gitlab, or Bitbucket. This way, other people can utilise it to work together. &lt;/p&gt;

&lt;p&gt;It isn't straightforward when you realise that there are many versions either in an archive or actively being worked. But don't worry about that just yet. Just focus on the small picture. Just know, that a reference to PR or Pull-Request is 'asking permission' to merge to different existences together.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Funny thing, I first used &lt;code&gt;git&lt;/code&gt; to play &lt;a href="https://www.kerbalspaceprogram.com/"&gt;KSP&lt;/a&gt; with my friends by sharing a repo of the save files and contributing different launch missions and ships. &lt;strong&gt;Super nerdy&lt;/strong&gt; way to bring multiplayer to a game&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  TDD
&lt;/h2&gt;

&lt;p&gt;'Test Driven Development' operates on the idea of writing tests for what you intend before you create it. Something like working in a traffic-light system you would say&lt;/p&gt;

&lt;p&gt;🔴 Write tests of your intention.&lt;/p&gt;

&lt;p&gt;🟢 Write code that makes those tests pass.&lt;/p&gt;

&lt;p&gt;🟡 Refactor that code for optimisation or performance.&lt;/p&gt;

&lt;p&gt;On top of that analogy, there are further four types of testing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Static&lt;/strong&gt; - Make sure there aren't any typos or type-errors (in Typescript). A common term for this is &lt;strong&gt;linting&lt;/strong&gt;, like, ESLint etc. Most static tests are baked into, or plugged into amazing text editors or IDE's these days.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Unit&lt;/strong&gt; - Does the code do what you think it does? Given two numbers, &lt;code&gt;1&lt;/code&gt; and &lt;code&gt;1&lt;/code&gt;, the function returns &lt;code&gt;2&lt;/code&gt; without doing anything else. Does it handle errors like passing a string rather than a number? Is the dom node filled out correctly with all a11y requirements for pure accessibility?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;console: Give me a number, dummy!
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Maybe it's a super functional and will accept an array of numbers too. 🎉&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Integration&lt;/strong&gt; - This is where your code plays nice with other code it's needing or interacts. With given data from an API, does the react/vue/svelt/HTML element do what you expect. As well as making sure the children elements are doing what they're supposed to.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;End-to-End&lt;/strong&gt; - From the developer's end to the user's end, is it all working cohesively? Can the user go through the motions of the site/app/program, and do that job-to-be-done without issue or error?&lt;/p&gt;

&lt;h2&gt;
  
  
  My Opinionated Workflow
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5POXTffq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/driueouct/image/upload/c_scale/v1589827576/Frame_7_lxxsjq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5POXTffq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/driueouct/image/upload/c_scale/v1589827576/Frame_7_lxxsjq.png" alt="Git Flow Diagram"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let me bring you back to my new flow in my projects going forward:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Git&lt;/code&gt; repos work like trees, a &lt;code&gt;master&lt;/code&gt; trunk branches off different iterations of the same project. So from there, I've branched off &lt;code&gt;release&lt;/code&gt;, &lt;code&gt;develop&lt;/code&gt;, and &lt;code&gt;develop/*&lt;/code&gt;. &lt;code&gt;master&lt;/code&gt; only exists because of being automatically created at the beginning. So you see I immediately branch into &lt;code&gt;develop&lt;/code&gt; and &lt;code&gt;develop/*&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In the beginning, &lt;code&gt;develop/*&lt;/code&gt; is where I'll live, writing &lt;strong&gt;unit&lt;/strong&gt; and &lt;strong&gt;integration&lt;/strong&gt; tests that will fail before nothing else. This branch is where I'll be blueprinting my intentions for the feature—ensuring that I've completed error handling too where necessary.&lt;/p&gt;

&lt;p&gt;On this hypothetical chart, &lt;code&gt;develop/[feature #1]&lt;/code&gt; (The Cyan coloured, 4th row) has a couple of commits. Here might be where I'm sharing my code with others asking for help (Another great use of shared remote repos!) and once I'm comfortable with my tests, code, and refactor, committing a PR to the &lt;code&gt;develop&lt;/code&gt; branch.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Always make a new branch when wanting to make a change to something existing, and always PR to merge it back in&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code&gt;develop&lt;/code&gt; is a moment to check End-to-End tests. Maybe it introduced a new bug no present previously. My latest feature might create an a11y issue previously unseen.&lt;/p&gt;

&lt;p&gt;Once everything is kosher, I can make another PR to the master branch to keep it as the one branch that is 'pure', where everything is working as intended and for my best knowledge, all tests are passing which means 🤞 - no bugs for the 90+% of users.&lt;/p&gt;

&lt;p&gt;This mentality to my commits will also mean that my &lt;code&gt;master&lt;/code&gt; branch might have code in it that's subject to change later, or yet utilised. Maybe this feature is purely integrating a service API or an algorithm, but its implementation is in a completely different realm.&lt;/p&gt;

&lt;p&gt;In the chart, I also have a &lt;code&gt;develop/[feature #2]&lt;/code&gt; branch, but the interesting one you'll see is that once it's gone through the motions, I have another branch. &lt;code&gt;release&lt;/code&gt;. I'll keep this purely as an anchor point to where the &lt;code&gt;master&lt;/code&gt; branch has everything that's needed to publish to the public. This way, I can keep on working on the next tests, the upcoming features, without worrying. &lt;/p&gt;

&lt;p&gt;If I'm working on a project with Continous Deployment like Netlify, if I committed to my &lt;code&gt;master&lt;/code&gt; branch, I could potentially send a request to Netlify to rebuild my website and publish these new developments that aren't ready for the public to utilise.&lt;/p&gt;

&lt;p&gt;And there we have it; my rubber duck debugged git workflow!&lt;/p&gt;




&lt;p&gt;I've started to enjoy these write-ups, I'm aiming for a more opinionated perspective than any tutorial. There are so many tutorials out there already that it wouldn't be beneficial for anyone. Instead, I'm aiming to document those moments of overlooked thought process when arriving at the result. Likewise, let me know your thoughts!&lt;/p&gt;

&lt;p&gt;✌️&lt;/p&gt;

</description>
      <category>git</category>
      <category>testing</category>
      <category>reflection</category>
    </item>
    <item>
      <title>Putting Typescript into Practice</title>
      <dc:creator>Alex Edwards</dc:creator>
      <pubDate>Wed, 29 Apr 2020 10:32:52 +0000</pubDate>
      <link>https://dev.to/_lexedwards/putting-typescript-into-practice-2g4m</link>
      <guid>https://dev.to/_lexedwards/putting-typescript-into-practice-2g4m</guid>
      <description>&lt;p&gt;After a few weeks of studying and brushing up on areas like Data Structures and Algorithms, I've recently finished a course on Typescript. After this, I started to revisit my favourite side project: a &lt;a href="https://github.com/lexedwards/react-color-contrast"&gt;WCAG-compliant colour palette app&lt;/a&gt;. I've been creating a Colour Picker UI component and realised that I wanted to break it off from the central system.&lt;/p&gt;

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

&lt;p&gt;Well, two reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;I don't need the values from the colour picker to be cluttering my central app state.&lt;/li&gt;
&lt;li&gt;I can easily add in a hook to relay the value object from the component, complete with methods that include pre-formatted values that work with the utility I'm using: 'color-convert'.
So, without further delay, here's my &lt;a href="https://github.com/lexedwards/Typed-ColorPicker"&gt;little colour picker&lt;/a&gt;:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--j72Px3jB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/driueouct/image/upload/c_scale%2Cw_200/v1588154864/Screen_Shot_2020-04-29_at_10.45.54_f4rzwz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--j72Px3jB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/driueouct/image/upload/c_scale%2Cw_200/v1588154864/Screen_Shot_2020-04-29_at_10.45.54_f4rzwz.png" alt="Color Picker Screenshot"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's not entirely spit-polished just yet, as I've discovered styling range input can be a bit tricky. There's a slight bug within mobile browsers where the sliders' border is styled rather than the fill. However, I completely removed the component and was able to implement Typescript onto it. The UI is completely tied together, with the gradients adjusting visually, along with a hook that emits an object with hex, rgb, hsl, and lab colour codes.&lt;/p&gt;

&lt;p&gt;Here's what I've learnt:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;My typing hygiene transposing the component wasn't the best. My previous JSX wasn't the best at ensuring types, and the data passed; specifically my abstractions!&lt;/li&gt;
&lt;li&gt;I completely forgot about the purpose of a *.d.ts file, so once I slapped my forehead for the oversight, VScode reopened all my files and told me to remove my explicit imports.&lt;/li&gt;
&lt;li&gt;The new CRA --template typescript CLI worked wonders to get set up quickly, but I can't tell you how many times I was opening docs to find out what components were what types.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most importantly, I found VScode was incredibly informative with errors. Suddenly my abstractions were too abstract and needed a rewrite, which made them more transparent. My state was interfering with handling invalid hex codes, and so I had to insert some middleware. All of this didn't run into errors in regular React + JSX; but given TSX, it made me double-check all my assumptions.&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>react</category>
      <category>javascript</category>
    </item>
    <item>
      <title>#2020 was a Non-Starter For Me</title>
      <dc:creator>Alex Edwards</dc:creator>
      <pubDate>Fri, 24 Apr 2020 17:12:29 +0000</pubDate>
      <link>https://dev.to/_lexedwards/2020-was-a-non-starter-for-me-pj1</link>
      <guid>https://dev.to/_lexedwards/2020-was-a-non-starter-for-me-pj1</guid>
      <description>&lt;p&gt;Something of a humbling experience, I left China in August '19 and ready to get back into Western life and a drive to get into Web Development and Software Engineering. I spend the past year studying what I could and building some smaller projects while learning. No Computer Science degree, no Boot camp. &lt;/p&gt;

&lt;p&gt;2020 was meant to be the start of something serious for me, and then Covid-19 starting to take a grip on the world and hiring-freezing started settling in. My job alerts began drying up, and now here I am.&lt;/p&gt;

&lt;p&gt;An inspiring conversation with a family friend in the job field, I got running again with patching holes in my knowledge and getting stuck into the events that were once in-person and now free online webcasts. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Now is the time to be taking this free-time and really developing what you can&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, I'm doing just that, I've scratched up on Data Structures and Algorithms, I've gotten my head around Typescript. I still have other lessons I want to learn like native mobile development, however, for now, I'm going for the spit-and-polish approach. I'm revisiting what I've learnt, old projects that I should have hosted online ages ago, and finally getting to grips with having an online presence again.&lt;/p&gt;

&lt;p&gt;I'm sat on quite extensive notes, and without plagiarising any course or material that I've learnt from, I do think that everything that I'm learning is best shared online rather than sat as 1s and 0s in my laptop. Not to mention that technology moves so fast right now, that it'll probably be outdated by this time next year. Just like how searching anything outside of MDN or other well-maintained sources, you can find yourself looking at outdated or hacky approaches. I mean, just google 'centring with CSS'.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>career</category>
    </item>
    <item>
      <title>My First Post 🎉</title>
      <dc:creator>Alex Edwards</dc:creator>
      <pubDate>Wed, 22 Apr 2020 11:23:54 +0000</pubDate>
      <link>https://dev.to/_lexedwards/my-first-post-2321</link>
      <guid>https://dev.to/_lexedwards/my-first-post-2321</guid>
      <description>&lt;p&gt;Here's the first post, and I'll never have to write one ever again!&lt;/p&gt;

&lt;p&gt;But it doesn't mean that I won't have other things to write.&lt;/p&gt;




&lt;p&gt;TL:DR;&lt;/p&gt;

&lt;p&gt;I chose an awful time to come back to the UK to change career paths after spending three years abroad. 2020 meant to be new employment, and then COVID-19 hit!&lt;/p&gt;




&lt;p&gt;Back in 2011, I wanted to be a photographer because that's what I loved doing. I loved capturing moments and preserving them endlessly. However, what I loved doing (The old stuff with raw chemicals and wooden boxes) was a very niche market that didn't even inspire my tutors at University. Resources dwindled, and I slumped into my temporary bar job that turned into a full-time position, eventually turning into being part of the management team. Fast forward to 2016 and a said f*k it to the wind and went travelling with the money I had a single backpack that was 60% camera. A year later, I did a TEFL course and started teaching in Asia for two years to sustain a life in an atmosphere that was unapologetic 'no-expectations' &amp;amp; multi-cultural by default.&lt;/p&gt;

&lt;p&gt;Some people thrive on that ladder of expectations and constantly unobtainable bar; I wasn't one of those at the time. The UK atmosphere at the time was to constantly side-hustle and over-work in a home that was falling apart but paid top-dollar for it. I'm sure a lot of places still are, but while travelling and trying my best to integrate locally, I found that it didn't have to be that way. &lt;/p&gt;

&lt;p&gt;Aside: I'm a person that like to quantify changes or results, think of it akin performance testing or sanity-checking the effort vs result. I'm genuinely curious if learning languages or immersing yourself in other cultures re-wires your brain. I've found that I think very differently after this experience abroad.&lt;/p&gt;




&lt;p&gt;I left China at the end of August '19, which wasn't perfect timing for me. However the country had gotten more hostile of foreign influence, and I'm sure everyone has seen some form of a headline about it over the past twelve months. Saved some money, visited a couple of places in Europe and spent the next few months finishing up the learning that I thought would be beneficial for the leap into Web Development. Something I had planned since 2017-2018. Well. That was the plan anyway.&lt;/p&gt;




&lt;p&gt;So, after re-adjusting to the new situation over here, I've started again with learning industry demands, making comprehensive documents (I &amp;lt;3 well-written Documentation) and I'm going to try at-least to start giving back to the communities that have given so much already.&lt;/p&gt;

</description>
      <category>firstpost</category>
    </item>
  </channel>
</rss>
