<?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: Sheelah Brennan</title>
    <description>The latest articles on DEV Community by Sheelah Brennan (@sheelah_b).</description>
    <link>https://dev.to/sheelah_b</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%2F131691%2Fbbb0f02c-b937-4656-ac3b-7afe64a95234.jpg</url>
      <title>DEV Community: Sheelah Brennan</title>
      <link>https://dev.to/sheelah_b</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sheelah_b"/>
    <language>en</language>
    <item>
      <title>Lessons from Ten Years in Web Development</title>
      <dc:creator>Sheelah Brennan</dc:creator>
      <pubDate>Wed, 01 Nov 2023 02:00:27 +0000</pubDate>
      <link>https://dev.to/sheelah_b/lessons-from-ten-years-in-web-development-blj</link>
      <guid>https://dev.to/sheelah_b/lessons-from-ten-years-in-web-development-blj</guid>
      <description>&lt;p&gt;It’s hard to believe that &lt;a href="https://sheelahb.com"&gt;my blog&lt;/a&gt; has posts that are now ten years old. That also means that I’ve been working in web development for 10 years! Back in 2013, I transitioned from working in site reliability engineering to working in frontend engineering. I spent most of the prior year ramping up on web technologies during a leave of absence from work that I was lucky to get, and in 2013 I started working in the field. That’s when the “real” learning — the learning-on-the-job phase — started.&lt;/p&gt;

&lt;p&gt;So what have I learned in the past 10 years of working in this field, and maintaining my (infrequent) web dev blogging?&lt;/p&gt;

&lt;h2&gt;
  
  
  Blogging and Note Taking Pays off
&lt;/h2&gt;

&lt;p&gt;Writing short blog posts (or notes somewhere at a minimum) on how you were able to troubleshoot and resolve a particular web dev issue is useful. These help your future self when you inevitably encounter that same issue later on. They also help people like you who are facing the same problem and are desperately searching the web for a solution. For example, I have a short blog post from 2014 (yes, a whopping nine years ago from now!) on how to handle PHP errors that can crop up when including SVG files. That post still gets frequent views today!&lt;/p&gt;

&lt;h2&gt;
  
  
  Tech Changes but the Underpinnings Remain
&lt;/h2&gt;

&lt;p&gt;Technologies come and go, but the underlying web tech -- HTML, CSS, and JavaScript -- remains. Back in 2013, I was way into &lt;a href="https://sass-lang.com"&gt;Sass&lt;/a&gt; and &lt;a href="http://beta.compass-style.org/help"&gt;Compass&lt;/a&gt;. I also loved building projects on top of &lt;a href="https://get.foundation"&gt;Foundation&lt;/a&gt;, a Bootstrap competitor that was Sass-based, and &lt;a href="https://github.com/oddbird/susy"&gt;Susy&lt;/a&gt;, a Sass-based grid framework. While these were my ride-or-dies at the time, the web has changed since then. For example, we can do so much more now with plain ol' CSS, with tools such as CSS grid and flexbox for layouts.&lt;/p&gt;

&lt;p&gt;I also was a diehard &lt;a href="https://gruntjs.com"&gt;Grunt&lt;/a&gt; user, and then a &lt;a href="https://gulpjs.com"&gt;Gulp&lt;/a&gt; user, and then later a &lt;a href="https://webpack.js.org"&gt;Webpack&lt;/a&gt; user. These were all different tools for running tasks and compiling code. The landscape changed pretty rapidly.&lt;/p&gt;

&lt;p&gt;I was way into jQuery when I was first learning web development in 2012. Now, we have a lot of JavaScript frameworks (see  below) at our fingertips, and with the advent of ES6 and more recent releases, vanilla JavaScript has gotten so much more powerful.&lt;/p&gt;

&lt;p&gt;The fundamental web technologies remain though, and if you're able to get comfortable with those, I've found you'll be able to pick up new web technologies and tools fairly quickly.&lt;/p&gt;

&lt;h2&gt;
  
  
  JavaScript Frameworks Come and Go
&lt;/h2&gt;

&lt;p&gt;JavaScript frameworks definitely come and go, but JavaScript fundamentals are always useful.&lt;/p&gt;

&lt;p&gt;Soon after I had gotten decent at jQuery, AngularJS was the hotness. I learned Angular (v1) at my first web development job and quickly saw how that road was paved with footguns. While the 2-way data binding was magical, it was so easy to end up with global state everywhere!&lt;/p&gt;

&lt;p&gt;React felt like a revelation when I tried it a couple years later. While that Angular-specific knowledge like directives was no longer relevant, the fundamentals of JavaScript like array &lt;code&gt;map()&lt;/code&gt; , loops, object destructuring, and other ES6 features were still very useful knowledge to have.&lt;/p&gt;

&lt;h2&gt;
  
  
  Interests Change
&lt;/h2&gt;

&lt;p&gt;Your interests also will eb and flow. Ride the wave and follow your curiosities. Back in 2013, I got into PHP and &lt;a href="https://wordpress.org"&gt;WordPress&lt;/a&gt;, and even migrated my site from &lt;a href="http://octopress.org"&gt;Octopress&lt;/a&gt;, an early static site generator, to WordPress for awhile. I got into building custom WordPress starter themes and used that for freelance projects. Then within a couple years I got really into JavaScript frameworks — first AngularJS and then React.&lt;/p&gt;

&lt;p&gt;These were fairly different libraries, but with some time learning and experimenting, I was able to ramp up on them and really enjoyed using them in turn.&lt;/p&gt;

&lt;p&gt;I then ended up migrating my blog back to a static site, this time based on Gatsby. I have no regrets that I followed my curiosities and dove into these different JavaScript frameworks, leaving the PHP and WordPress world behind.&lt;/p&gt;

&lt;p&gt;Your career interests may change too, and that's expected. "Don't die wondering!" is something I like to remind myself when considering a pivot. I went from frontend engineering in a giant tech company, to frontend engineering in a media startup, to frontend engineering in a product-turned-ecommerce startup, to design systems engineering at a fintech startup, to my current role as a design technologist at an enterprise software company.  Changing roles like this, either by transferring within a company or by switching companies completely, is how you find out what you really like and really don't like.&lt;/p&gt;

&lt;h2&gt;
  
  
  User Needs Remain Unchanged
&lt;/h2&gt;

&lt;p&gt;It's easy to get wrapped up in different tech stacks and JavaScript frameworks, focusing on the developer experience at the expense of everything else. At the end of the day, the user experience is most important.  Taking the time early on in your projects to consider the UX, web performance, and accessibility goes a long way to making the web a better place. Your users will thank you!&lt;/p&gt;

&lt;p&gt;Featured image by &lt;a href="https://unsplash.com/@langao"&gt;Lan Gao&lt;/a&gt; via Unsplash&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>webdev</category>
      <category>blogging</category>
      <category>career</category>
    </item>
    <item>
      <title>Favorite TypeScript Resources</title>
      <dc:creator>Sheelah Brennan</dc:creator>
      <pubDate>Tue, 20 Dec 2022 21:40:47 +0000</pubDate>
      <link>https://dev.to/sheelah_b/favorite-typescript-resources-150c</link>
      <guid>https://dev.to/sheelah_b/favorite-typescript-resources-150c</guid>
      <description>&lt;p&gt;TypeScript has become a mainstay in a lot of open source projects these days, and it's also a "preferred skill" in many web development and front-end engineering job posts.&lt;/p&gt;

&lt;p&gt;I started learning TypeScript a couple years ago, when i started a new job on a design systems engineering team with a entire codebase written entirely in TypeScript. I remember worrying about being impossibly slow at building new components because of my lack of TypeScript experience.&lt;/p&gt;

&lt;p&gt;In the end, it wasn't that bad, as I had teammates point me in the direction of some useful TypeScript learning resources, and I've found some more great ones since then. I will say that having the opportunity to learn TypeScript while working on a team is probably the best scenario. You will at times get stuck on something with a cryptic TypeScript error, and having someone at work to pair with when you're stuck is invaluable.&lt;/p&gt;

&lt;p&gt;Here's some TypeScript learning resources that have been helpful for me.&lt;/p&gt;

&lt;h2&gt;
  
  
  Base Resources
&lt;/h2&gt;

&lt;p&gt;These are some useful base resources to get your started.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://basarat.gitbook.io/typescript"&gt;TypeScript Deep Dive&lt;/a&gt; (free): A great overall reference. If you prefer learning via videos, the author, Basarat, has a lot of &lt;a href="https://www.youtube.com/@basarat/videos"&gt;YouTube videos&lt;/a&gt; available as well.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.smashingmagazine.com/printed-books/typescript-in-50-lessons"&gt;TypeScript in 50 Lessons&lt;/a&gt; (paid): I learned all the TypeScript fundamentals from this book. I love that it's broken up into bite-size lessons, so you can learn a little bit at a time. Also, the examples use real-world scenarios, so they're easier to follow.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.typescriptlang.org/docs"&gt;TypeScript Docs&lt;/a&gt; (free): A great starter resource to learn terminology, so that you can do a web search with the right words :)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://frontendmasters.com/courses/typescript-v3"&gt;TypeScript Fundamentals, v3&lt;/a&gt; (paid): If you like learning by watching video courses and you have access to Frontend Masters, this is a great course. I took the v2 one but this is an updated version which will cover all the latest TypeScript features. Mike North is a solid instructor. If you are interested in learning how to convert an existing JavaScript project to TypeScript, check out the &lt;a href="https://frontendmasters.com/courses/typescript-v2"&gt;v2&lt;/a&gt; version of this course.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://kentcdodds.com/blog?q=typescript"&gt;Kent C. Dodds Blog&lt;/a&gt;: Kent C. Dodds has a fair number of blog posts about TypeScript that are useful as well.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  React &amp;amp; TypeScript Resources
&lt;/h2&gt;

&lt;p&gt;There are a lot of best practices that exist for using TypeScript in React projects. I highly recommend checking some of these out if you're using React and are new to TypeScript.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://react-typescript-cheatsheet.netlify.app"&gt;React TypeScript Cheat Sheet&lt;/a&gt; (free): This is my go-to React &amp;amp; TypeScript resource. This covers the basic best practices for doing things like creating components, creating types for React component props, etc. Even the TypeScript documentation links to this site, so you know it's a good one.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.freecodecamp.org/news/typescript-for-react-developers"&gt;TypeScript for React Developers&lt;/a&gt; (free): This FreeCodeCamp course covers all the fundamentals.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Bonus: TypeScript Error Message Decoder
&lt;/h2&gt;

&lt;p&gt;The error messages given by the TypeScript compiler can be very hard to understand. To help with this, try this awesome &lt;a href="https://marketplace.visualstudio.com/items?itemName=mattpocock.ts-error-translator"&gt;VS Code Total Typescript plugin&lt;/a&gt;. You won't regret it!&lt;/p&gt;

&lt;p&gt;Featured image by &lt;a href="https://unsplash.com/@kimberlyfarmer"&gt;Kimberly Farmer&lt;/a&gt; via Unsplash&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>webdev</category>
      <category>typescript</category>
    </item>
    <item>
      <title>So What is a Design Technologist, Anyways?</title>
      <dc:creator>Sheelah Brennan</dc:creator>
      <pubDate>Mon, 28 Nov 2022 04:30:03 +0000</pubDate>
      <link>https://dev.to/sheelah_b/so-what-is-a-design-technologist-anyways-52ep</link>
      <guid>https://dev.to/sheelah_b/so-what-is-a-design-technologist-anyways-52ep</guid>
      <description>&lt;p&gt;As you've browsed the tech job boards this year, you may have started noticing postings for a role called "design technologist." So what exactly is a design technologist, anyways?&lt;/p&gt;

&lt;p&gt;After spending the last ~9 months working as a design technologist, I wanted to share some insights on this role, and why it may or may not be a great fit for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Core Focus
&lt;/h2&gt;

&lt;p&gt;The core focus of a design technologist role is usually to serve as a liason (or "glue", if you like analogies) between design and engineering teams. Since designers and engineers, even those in front-end engineering roles, often come from very different backgrounds and have different skill sets, there is often a gap in understanding between these two roles or teams. This is where design technologists come in.&lt;/p&gt;

&lt;p&gt;Design technologists often have a hybrid skillset of both design and front-end engineering.  However, because the UX/UI design and front-end engineering fields are so broad even on their own, it's very common that a design technologist will be stronger in either design or front-end engineering. For example, I have taken a bunch of design courses and have done some UI design work, but I'm definitely stronger on the front-end engineering side of things.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Responsibilities
&lt;/h2&gt;

&lt;p&gt;Design technologists commonly serve as key partners to a design team, empowering them to do their best work. What can this look like in practice? Here's some common responsibilities for a design technologist.&lt;/p&gt;

&lt;h3&gt;
  
  
  Design System Champion And/Or Contributor
&lt;/h3&gt;

&lt;p&gt;Design technologists often are found at companies that have a design system and design system component library. They may serve as a champion for the design system component library, helping teams to adopt the library in their own projects or even contributing new components to the component library. They also may help designers ramp up on the library and contribute additional design system documentation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Design Tools Developer
&lt;/h3&gt;

&lt;p&gt;Designers often have workflows and processes that could benefit from automation. That's where design technologists can come in. Design technologists often build tools to support designers, such as custom Figma plugins or entire web applications for internal use.&lt;/p&gt;

&lt;p&gt;Over the past 9 months, this category has been where the majority of my time has been spent.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prototyper
&lt;/h3&gt;

&lt;p&gt;Designers can easily create designs for a new product or new workflow for an existing product, but how do they know if its the &lt;em&gt;right&lt;/em&gt; design and something that's feasible to build for the web? Design technologists can work in a prototyping capacity, collaborating closely with designers to build out a new UI feature in code. The goals of the prototype can vary quite a bit! A prototype can be created to help designers visualize what a design will look like on the web, allowing them to explore multiple ideas. Prototypes may also get created to help make sure that a UI feature will be performant, intuitive, and accessible, or even to serve as a UI to use for user testing by UX researchers.  The fidelity of the prototype also varies quite a bit, depending on how it will be used.&lt;/p&gt;

&lt;p&gt;In my time as a design technologist, this category has been another one that I've spent time in this year, and it's my personal favorite 🙂&lt;/p&gt;

&lt;h3&gt;
  
  
  Accessibility Specialist
&lt;/h3&gt;

&lt;p&gt;Design technologists can also have a specialty in a certain area, such as accessibility. For example, a design technologist well-versed in &lt;a href="https://www.w3.org/WAI/standards-guidelines/wcag/" rel="noopener noreferrer"&gt;WCAG standards&lt;/a&gt; may help designers to design with all accessibility concerns in mind, or they may help front-end engineers to built fully accessible UI components.&lt;/p&gt;

&lt;h2&gt;
  
  
  Is the Design Technologist Role for You?
&lt;/h2&gt;

&lt;p&gt;If you like design and front-end engineering, and you enjoy collaborating with designers and engineering teams, the design technologist role might be a great fit for you. It's a great role for "unicorns", often called hybrid designer/developers or UX engineers.  In addition, it's a great fit for front-end engineers who want to try something a bit different from design system engineering work, and who enjoy working on a couple of different things at once, instead of having a single focus.&lt;/p&gt;

&lt;p&gt;If you prefer primarily interacting with engineering teams, are focused on having a specific engineering job title, or concerned about not being considered a "real" engineer in what would be a hybrid role, a design technologist role may not be a great choice for you.&lt;/p&gt;

&lt;p&gt;For more food for thought, check out the &lt;a href="https://designtechnologist.club/book/who-is-a-design-technologist/" rel="noopener noreferrer"&gt;design technologist club's description of the role&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;That's all for now! I hope this provided some insight into the design technologist role. If you have thoughts or questions on this role, drop a note in the comments.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Image by &lt;a href="https://unsplash.com/@jessbaileydesigns" rel="noopener noreferrer"&gt;Jess Bailey&lt;/a&gt; via Unsplash&lt;/em&gt;&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>design</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Frontend Engineer vs Design Systems Engineer</title>
      <dc:creator>Sheelah Brennan</dc:creator>
      <pubDate>Fri, 10 Sep 2021 20:52:51 +0000</pubDate>
      <link>https://dev.to/sheelah_b/frontend-engineer-vs-design-systems-engineer-2jnn</link>
      <guid>https://dev.to/sheelah_b/frontend-engineer-vs-design-systems-engineer-2jnn</guid>
      <description>&lt;p&gt;You've probably heard about design systems and seen job posts for design systems engineers or for UX engineers, who often work on a design system.&lt;/p&gt;

&lt;p&gt;First of all, what is a design systems engineer? It's an engineer working on a design system, who may have some interest or experience in design fundamentals like colors and typography. A design system is a set of reusable components along with usage guidelines which can be used to create all kinds of new layouts and pages. It can really speed design and development for product work, since designers and engineers will use the components as building blocks instead of starting from scratch.&lt;/p&gt;

&lt;p&gt;Is this type of role for you? Today I'm going to highlight some of the differences between a frontend engineering role and a design systems engineering role.&lt;/p&gt;

&lt;h2&gt;
  
  
  Collaboration with designers is extra important
&lt;/h2&gt;

&lt;p&gt;In a design systems engineering role, you'll spend a lot of time collaborating with designers. You'll review component designs and and work together with designers during new component builds. You may even prototype new component UIs during the development phase in order to get early feedback from design systems designers. Communication skills are important!&lt;/p&gt;

&lt;h2&gt;
  
  
  More planning before component development
&lt;/h2&gt;

&lt;p&gt;In product work, frontend engineers often move straight into the development phase when building a new feature. This is quite different from design system engineering, when there is normally a lot of planning that takes place before any code is written.&lt;/p&gt;

&lt;p&gt;During this planning phase, design system engineers will review the final component designs and decide on the best API to use for the component. The goal is to help ensure that the final component is easy for other frontend engineers to use, in addition to having all the needed functionality.&lt;/p&gt;

&lt;h2&gt;
  
  
  Other engineers are your customers
&lt;/h2&gt;

&lt;p&gt;As an engineer on a design systems team, your customers are the consumers of your system -- other engineers. This contrasts with being an engineer on a product team, where your customers may be external users of the product. Being able to talk often with engineers using your design system in order to get their feedback is really important. Being in touch with your customers also helps to gauge any pain points that design systems users are encountering.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing is really important
&lt;/h2&gt;

&lt;p&gt;Component tests are always good to have in place, but in a design system, where possibly hundreds or even thousands of engineers will be using your system, tests are critical. Having tooling in place for accessibility testing and UX regression testing also is very valuable for design systems teams.&lt;/p&gt;

&lt;h2&gt;
  
  
  Accessibility is a must-have
&lt;/h2&gt;

&lt;p&gt;Accessibility is unfortunately often an afterthought when working as a frontend engineer on a product team. When working on a design system, building accessible components is a core foundation of the role. Most US-based design systems aim to follow &lt;a href="https://www.w3.org/TR/WCAG21/"&gt;WCGAG 2.1 Guidelines&lt;/a&gt; for components. As a new design systems engineer, you'll be ramping up on these guidelines and learn how to best implement them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Documentation is core to the system
&lt;/h2&gt;

&lt;p&gt;Because the success of a design system is measured based on adoption, documentation on components and how to use them is key. Teams often use &lt;a href="https://storybook.js.org/"&gt;Storybook&lt;/a&gt; or a similar tool to allow customers to see and interact with components. Documenting usage patterns for each component, along with any guidelines for ensuring accessibility, is also critical.&lt;/p&gt;

&lt;h2&gt;
  
  
  Support is part of the role
&lt;/h2&gt;

&lt;p&gt;As a design systems engineer, helping engineers adopt and use the design system is a big part of the role. Engineers may discover component bugs that need to be addressed, or they may have ideas for ways to make components easier to use. Fielding questions on component usage and fixing component bugs are common activities for design systems team members.&lt;/p&gt;

&lt;h2&gt;
  
  
  Infrastructure and version management comes to the forefront
&lt;/h2&gt;

&lt;p&gt;On a design systems team, engineers often work in a monorepo, where different aspects of the system, like components and icons, may be broken up into different npm packages with independent versioning. This makes adopting the system easier for users, as they can upgrade to new package versions on their own time frame. This also makes managing changes over time easier for design systems engineer.&lt;/p&gt;

&lt;p&gt;Experience or interest in &lt;a href="https://semver.org/"&gt;semantic versioning standards&lt;/a&gt;, tools like &lt;a href="https://github.com/lerna/lerna"&gt;lerna&lt;/a&gt;, which is often use for automating package versioning, and tools for continuous integration is really valuable on a design systems team.&lt;/p&gt;

&lt;p&gt;I hope this helps with anyone considering moving into design systems engineering! It's definitely a growing specialty. Do you have more thoughts on the differences between frontend engineering and design systems engineering? Leave a comment!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Image by &lt;a href="https://unsplash.com/@davidpisnoy"&gt;David Pisnoy&lt;/a&gt; via Unsplash&lt;/em&gt;&lt;/p&gt;

</description>
      <category>systems</category>
      <category>programming</category>
      <category>frontend</category>
      <category>design</category>
    </item>
    <item>
      <title>Five Tips for Effective Github Pull Request Descriptions</title>
      <dc:creator>Sheelah Brennan</dc:creator>
      <pubDate>Wed, 01 Sep 2021 14:47:32 +0000</pubDate>
      <link>https://dev.to/sheelah_b/five-tips-for-effective-github-pull-request-descriptions-2e4o</link>
      <guid>https://dev.to/sheelah_b/five-tips-for-effective-github-pull-request-descriptions-2e4o</guid>
      <description>&lt;p&gt;A big part of collaborating with other developers on a project, whether it be at work or on an open source project, is creating and reviewing Github pull requests. Today I'm sharing five tips for creating effective Github pull request descriptions. These tips will help you ensure your pull request is easy for reviewers to understand and thoroughly review. They will also help your pull request to get reviewed more quickly, by being explicit about what was changed and how to QA it.&lt;/p&gt;

&lt;p&gt;Let's dive in to sections worth including in a pull request description.&lt;/p&gt;

&lt;h2&gt;
  
  
  High-Level Details on What Was Changed
&lt;/h2&gt;

&lt;p&gt;Providing a concise bulleted list of what was changed is a great first step. Linking to a ticket or open Github issue is great, but let's be honest -- who wants to have to put the pieces together on their own? Make it easy for your reviewer by noting the key changes included in your pull request.&lt;/p&gt;

&lt;p&gt;If you are implementing something that was scoped out in an engineering proposal, link to that document. Also, if you are implementing a UI feature, link to the designs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Open Questions
&lt;/h2&gt;

&lt;p&gt;You may have some lingering questions relating to the changes that you had to make. Why not call those out in your pull request description, if you didn't already have a discussion about them beforehand? In addition, if you're looking for feedback on specific changes that you made, call those out as well so that your reviewer can provide input.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Test
&lt;/h2&gt;

&lt;p&gt;This is an important one that is often missed. Make it easy for your reviewer by providing explicit steps on how to test your changes. It's often nice to use a &lt;a href="https://docs.github.com/en/issues/tracking-your-work-with-issues/about-task-lists#creating-task-lists"&gt;checklist format&lt;/a&gt;, which is easy to do with markdown, so that your reviewer can even go through the list and check off completed steps. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="p"&gt;-&lt;/span&gt; [] Start dev server at http://localhost:3000/about-us
&lt;span class="p"&gt;-&lt;/span&gt; [] Confirm that the navigation menu's open/close feature now works on mobile
&lt;span class="p"&gt;-&lt;/span&gt; [] Confirm that the navigation menu still works the same on tablet and desktop widths
&lt;span class="p"&gt;-&lt;/span&gt; [] Check that tests added are complete
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If your pull request includes the addition of a new library, note that in the steps so that your reviewer knows to install it first.&lt;/p&gt;

&lt;h2&gt;
  
  
  Screenshots
&lt;/h2&gt;

&lt;p&gt;For UI changes, include one or more screenshots of the completed feature. If you fixed a bug, it's nice to include a "before" and "after" screenshot so that your reviewer can see exactly what you fixed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Notes
&lt;/h2&gt;

&lt;p&gt;If you have any other notes to add for your reviewer, such as specific aspects of the work that are out of scope or things to address later, this is the section to note them.&lt;/p&gt;

&lt;p&gt;That's all! One final tip: once you're landed on the appropriate format for your teams' pull request descriptions, you can create a &lt;a href="https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/creating-a-pull-request-template-for-your-repository"&gt;pull request template&lt;/a&gt; for your Github repository, so that all pull requests will get those sections included by default.&lt;/p&gt;

&lt;p&gt;If you have more ideas for effective Github pull request descriptions, please share in the comments :).&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Image by &lt;a href="https://unsplash.com/@glenncarstenspeters"&gt;Glenn Carstens-Peters&lt;/a&gt; via Unsplash&lt;/em&gt;&lt;/p&gt;

</description>
      <category>github</category>
      <category>programming</category>
      <category>collaboration</category>
      <category>git</category>
    </item>
    <item>
      <title>React Testing Library: Tips and Tricks</title>
      <dc:creator>Sheelah Brennan</dc:creator>
      <pubDate>Fri, 20 Aug 2021 19:37:14 +0000</pubDate>
      <link>https://dev.to/sheelah_b/react-testing-library-tips-and-tricks-42me</link>
      <guid>https://dev.to/sheelah_b/react-testing-library-tips-and-tricks-42me</guid>
      <description>&lt;p&gt;&lt;strong&gt;Update (9/6/22):&lt;/strong&gt; This article has been updated to stay in line with current React Testing Library best practices.&lt;/p&gt;

&lt;p&gt;Testing front-end web applications has gotten a lot easier! But that doesn't mean it doesn't involve some ramp-up on tooling. In this article I'll provide some tips and tricks for getting started and ramping up quickly with &lt;a href="https://testing-library.com/docs/react-testing-library/intro"&gt;React Testing Library&lt;/a&gt;, the most popular tool for React component testing today.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://testing-library.com/docs/react-testing-library/intro"&gt;docs&lt;/a&gt; are great, so if you're new to the library, you should definitely take a quick look there.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deciding on Queries to Use
&lt;/h2&gt;

&lt;p&gt;In order to write tests, you'll use the library to render your component and then write one or more queries to find certain DOM elements on the page. The question you'll have is which query to use! There are &lt;a href="https://testing-library.com/docs/queries/about"&gt;a lot of them&lt;/a&gt;. The best practice here is to query for actual visible elements in the DOM, such as querying for buttons with certain text, form inputs, images with certain alt text, etc.&lt;/p&gt;

&lt;p&gt;Here's an example of querying for a button with "Read More" text:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="o"&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="s2"&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;/read more/i&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These queries can be used to look for certain text elements too! Here's an example of querying for a &lt;code&gt;h1&lt;/code&gt; heading:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="o"&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="s2"&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="na"&gt;level&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;h1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Role-based Queries
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;findByRole&lt;/code&gt; and &lt;code&gt;getByRole&lt;/code&gt; queries are the ones that you will likely be reaching for the most, and any element listed in this &lt;a href="https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques#roles"&gt;roles list&lt;/a&gt; can be queried for. The bonus of using these roles-based queries is that you're helping to ensure that your components are accessible and available for assistive technology like screen readers!&lt;/p&gt;

&lt;p&gt;For the full list of role-based queries available, see the &lt;a href="https://testing-library.com/docs/queries/byrole"&gt;React testing library docs&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  findBy* vs getBy* Queries
&lt;/h3&gt;

&lt;p&gt;So what's the difference between &lt;code&gt;findBy*&lt;/code&gt; and &lt;code&gt;getBy*&lt;/code&gt; queries? For any test that involves asynchronous behavior, like checking that a message is rendered after a user clicks on a submit button, &lt;code&gt;findBy*&lt;/code&gt; queries are the ones to reach for. For tests that don't involve asynchronous behavior, like checking that a heading with certain text is shown when component is rendered, &lt;code&gt;getBy*&lt;/code&gt; queries work great.&lt;/p&gt;

&lt;p&gt;Note that with &lt;code&gt;findBy*&lt;/code&gt; queries, you'll use &lt;code&gt;await&lt;/code&gt; to wait for the element you're querying for to be found:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;confirmation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&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;findByRole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&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="na"&gt;level&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;h3&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can think of &lt;code&gt;findBy*&lt;/code&gt; queries as a shortcut for running a &lt;code&gt;getBy*&lt;/code&gt; query followed by an &lt;code&gt;await waitFor()&lt;/code&gt; call. The following two approaches would accomplish the same thing but you'll see that using &lt;code&gt;findBy*&lt;/code&gt; is more concise:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Using findByRole() to wait for a toast to appear&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;toast&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&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;findByRole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&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="na"&gt;level&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;h3&lt;/span&gt;&lt;span class="dl"&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Confirmed!&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;toast&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toBeDefined&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// This is optional since the line above will fail if the toast isn't found&lt;/span&gt;

&lt;span class="c1"&gt;// Using getByRole() to wait for a toast to appear&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;waitFor&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;toast&lt;/span&gt; &lt;span class="o"&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="s2"&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="na"&gt;level&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;h3&lt;/span&gt;&lt;span class="dl"&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Confirmed!&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;toast&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toBeDefined&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;h3&gt;
  
  
  getBy* vs queryBy* Queries
&lt;/h3&gt;

&lt;p&gt;You'll also notice that there are both &lt;code&gt;getBy*&lt;/code&gt; queries and &lt;code&gt;queryBy*&lt;/code&gt; queries. The main difference is that &lt;code&gt;getBy*&lt;/code&gt; and &lt;code&gt;findBy*&lt;/code&gt; queries return the actual DOM element matched and throw an error if the element is not found. &lt;code&gt;queryBy*&lt;/code&gt; queries are similar in that they also return the actual DOM node matched, but they return &lt;code&gt;null&lt;/code&gt; if no match was found. How do you know which to use? Reach for &lt;code&gt;getBy*&lt;/code&gt; and &lt;code&gt;findBy*&lt;/code&gt; queries unless you want to test for an element that may not be present. In that case you'll want to use &lt;code&gt;queryBy*&lt;/code&gt; queries. An example of a good use case for &lt;code&gt;queryBy*&lt;/code&gt; queries is when you want to test that an element is not present.&lt;/p&gt;

&lt;h3&gt;
  
  
  Querying for Single and Multiple Items
&lt;/h3&gt;

&lt;p&gt;With React Testing Library, you'll notice that there are both &lt;code&gt;getAllBy*&lt;/code&gt; and &lt;code&gt;getBy*&lt;/code&gt; queries. When you're just searching for a single element, you'll want to use a &lt;code&gt;getBy*&lt;/code&gt; or &lt;code&gt;findBy*&lt;/code&gt; query. For cases where you want to query for multiple items, such as an unordered list of elements, you'll want to use a &lt;code&gt;getAllBy*&lt;/code&gt; or &lt;code&gt;findAllBy*&lt;/code&gt; query.&lt;/p&gt;

&lt;h2&gt;
  
  
  Debugging Errors or Missing Elements
&lt;/h2&gt;

&lt;p&gt;Sometimes your tests will fail unexpectedly and you'll wonder what is being rendered. Don't worry -- there's a utility for that! Use &lt;code&gt;screen.debug()&lt;/code&gt; inside your test and you'll then get a full printout of what was rendered. If your component renders a lot of of content and &lt;code&gt;screen.debug()&lt;/code&gt; output is getting cut off, specify a longer max output length by doing something like &lt;code&gt;screen.debug(undefined, 50000)&lt;/code&gt; to print 50000 lines. Alternatively, you can print the output for a given DOM element that you queried for with &lt;code&gt;screen.debug(myElement, 500000)&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing Hidden Elements
&lt;/h2&gt;

&lt;p&gt;Sometimes you'll want to test a component that is hidden. For example, an element might have &lt;code&gt;aria-hidden=true&lt;/code&gt; on it if it has surrounding label text. In this case, if you query for the element, you'll find that you don't get any matching element found.&lt;/p&gt;

&lt;p&gt;The fix is to include &lt;code&gt;{ hidden: true }&lt;/code&gt; in your query. Then the library will also include hidden elements in query results.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;buttons&lt;/span&gt; &lt;span class="o"&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="s2"&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;hidden&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;See the &lt;a href="https://testing-library.com/docs/queries/byrole/#hidden"&gt;documentation on this&lt;/a&gt; for more information.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing Click Behaviors
&lt;/h2&gt;

&lt;p&gt;For tests that depend on a user interaction, like a button click, to happen, you'll want to simulate that interaction in your test first. To do this, you can use the &lt;a href="https://testing-library.com/docs/ecosystem-user-event"&gt;userEvent&lt;/a&gt; library:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;userEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setup&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;submitButton&lt;/span&gt; &lt;span class="o"&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="s2"&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;/sign up/i&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;user&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;submitButton&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;toast&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&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;findByRole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&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="na"&gt;level&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;h3&lt;/span&gt;&lt;span class="dl"&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Confirmed&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;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;toast&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toBeDefined&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is also an older utility called &lt;a href="https://testing-library.com/docs/dom-testing-library/api-events/#fireevent"&gt;fireEvent&lt;/a&gt; that you can use, but using userEvent is preferred since it more closely simulates an actual user interaction.&lt;/p&gt;

&lt;h2&gt;
  
  
  More Test Assertion Options
&lt;/h2&gt;

&lt;p&gt;To have access to a wider array of Jest assertion options to use in your tests, I highly recommend installing the &lt;a href="https://github.com/testing-library/jest-dom"&gt;jest-dom&lt;/a&gt; library. It works great with React testing library and lets you write some useful assertions without extra legwork. For example, you can test that a link element has a certain &lt;code&gt;href&lt;/code&gt; attribute like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;link&lt;/span&gt; &lt;span class="o"&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="s2"&gt;link&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Get Started&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;link&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toHaveAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;href&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="s2"&gt;https://example.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Query Helpers and Tools
&lt;/h2&gt;

&lt;p&gt;To help with finding an appropriate query, there is a useful Chrome extension that you can try that's called &lt;a href="https://chrome.google.com/webstore/detail/testing-playground/hejbmebodbijjdhflfknehhcgaklhano?hl=en"&gt;Testing Playground&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To help ensure that you're following all best practices for the library, there's also an &lt;a href="https://testing-library.com/docs/ecosystem-eslint-plugin-testing-library"&gt;ESLint plugin&lt;/a&gt; that's worth installing in your project.&lt;/p&gt;

&lt;p&gt;That's all! I'd love to hear what your favorite React Testing Library tip is. Feel free to share in the comments or &lt;a href="https://twitter.com/@sheelah_b"&gt;find me on Twitter&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Featured image by &lt;a href="https://unsplash.com/@joerga"&gt;Jörg Angeli&lt;/a&gt; via Unsplash&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>testing</category>
      <category>react</category>
    </item>
    <item>
      <title>Debugging CSS: Some Tips and Tricks</title>
      <dc:creator>Sheelah Brennan</dc:creator>
      <pubDate>Thu, 24 Dec 2020 04:27:37 +0000</pubDate>
      <link>https://dev.to/sheelah_b/debugging-css-some-tips-and-tricks-bek</link>
      <guid>https://dev.to/sheelah_b/debugging-css-some-tips-and-tricks-bek</guid>
      <description>&lt;p&gt;We've all been there. You're working on a new piece of functionality and have the markup done. Now it's time to work on the styles. No problem, right? You add the base styles and when the page reloads with the changes applied, suddenly the layout is broken. You sigh, knowing that it might be a long day as you're up against a tight deadline.&lt;/p&gt;

&lt;p&gt;CSS can be tricky at times. In this article I'll provide some strategies I've used for troubleshooting CSS when things are not working as expected. Hopefully one of these can help get you out of frustration mode and back into "getting things done" mode 🙂.&lt;/p&gt;

&lt;h2&gt;
  
  
  Generic Layout Issues
&lt;/h2&gt;

&lt;p&gt;One of my most commonly used strategies when facing any kind of layout issue is to add an outline around a parent element's children. This lets me see whether the children are where I thought they would be and whether they have the expected dimensions. You can use a rule like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.element&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;outline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="no"&gt;red&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;If the layout issue is more complex and you need to debug the layout of the entire page, you can add outlines for every element on the page using different colors. This is a lot of lines to look at, but it can be helpful. In your browser developer tools, open your console tab and type this JavaScript snippet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;;[].&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;outline&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1px solid #&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;~~&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;))).&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;16&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;An alternative strategy for debugging the layout of the entire page is to place a background color on all elements:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nd"&gt;:nth-child&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;n&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rgba&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  CSS Grid or Flexbox Issues
&lt;/h2&gt;

&lt;p&gt;In addition to using the generic layout issue strategies above, I like to take advantage of Firefox or Chrome's developer tools to help with these issues. For example, in Firefox's developer tools, you can use the layout tab to inspect a grid or flex parent. If you inspect a grid parent, you'll then see lines added, allowing you to visualize the grid. Doing this can help you also discover any bugs caused by adding an extra wrapper div or element between your parent and child elements which can break your grid or flex layout.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsheelahb.com%2Fstatic%2Fb1bc4de423403728186cc6e3959c0c5d%2F9fc2b%2Fcss-grid-inspection.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsheelahb.com%2Fstatic%2Fb1bc4de423403728186cc6e3959c0c5d%2F9fc2b%2Fcss-grid-inspection.jpg" alt="CSS grid inspection"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Clicking on the &lt;code&gt;grid&lt;/code&gt; waffle icon on the left automatically selects it on the right.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsheelahb.com%2Fstatic%2Ffd66a03d26d9224879681bdb8a889f4a%2F7ab6d%2Fcss-grid-lines.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsheelahb.com%2Fstatic%2Ffd66a03d26d9224879681bdb8a889f4a%2F7ab6d%2Fcss-grid-lines.jpg" alt="CSS grid lines"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Page Overflow Issues
&lt;/h2&gt;

&lt;p&gt;For debugging an unexpected horizontal scrollbar, my favorite strategy is outlined in this &lt;a href="https://css-tricks.com/findingfixing-unintended-body-overflow/" rel="noopener noreferrer"&gt;CSS Tricks article&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Browser or Mobile-Only Bugs
&lt;/h2&gt;

&lt;p&gt;Could what you're seeing be a browser-specific bug? It's worth testing the page out on other browsers and on a mobile device (especially on Safari mobile!) if you can. If you're only seeing the issue on one browser, then you can narrow down the source of the bug.&lt;/p&gt;

&lt;p&gt;For example, I've regularly ran into flexbox issues that are Safari-specific. I've discovered these by testing in other browsers and confirming that the issue only shows up in Safari. A good reference of Flexbox browser-specific bugs is &lt;a href="https://github.com/philipwalton/flexbugs" rel="noopener noreferrer"&gt;Philip Walton's flexbugs repo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I've also ran into issues in the past with how &lt;a href="https://medium.com/@susiekim9/how-to-compensate-for-the-ios-viewport-unit-bug-46e78d54af0d" rel="noopener noreferrer"&gt;mobile Safari handles &lt;code&gt;vh&lt;/code&gt; units&lt;/a&gt;, confirmed by testing on Android and seeing that the issue wasn't appearing there.&lt;/p&gt;

&lt;h2&gt;
  
  
  Typos
&lt;/h2&gt;

&lt;p&gt;Could it just be a CSS typo? It happens to the best of us. Even the smallest typo can cause your CSS rule not to get applied. A useful strategy here is to use your browser developer tools to inspect the element of the page where you're seeing the bug. See what CSS is getting applied. If you see your rule there and it's crossed out, it's not getting applied.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsheelahb.com%2Fstatic%2F695e05d329f0906bdbbb4cf19c2b3f70%2Ff58be%2Fcss-typo.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsheelahb.com%2Fstatic%2F695e05d329f0906bdbbb4cf19c2b3f70%2Ff58be%2Fcss-typo.jpg" alt="In Firefox Developer Tools, a caution symbol and crossed out text indicating that the color rule wasn't applied. This looks very similar in Chrome."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A preventative strategy here is to use a code editor that includes syntax highlighting for CSS, like VS Code. This won't catch every single possible typo, but it will call out things like invalid property names and it will make invalid property values easier to catch.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsheelahb.com%2Fstatic%2Fa5b8b0620366710862fb92d7cb2837e4%2Fee53f%2Fcss-rule-typo.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsheelahb.com%2Fstatic%2Fa5b8b0620366710862fb92d7cb2837e4%2Fee53f%2Fcss-rule-typo.jpg" alt="VS Code with an invalid property and invalid color value"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Markup Issues
&lt;/h2&gt;

&lt;p&gt;Another source of bugs is typos in HTML markup. For example, you might have forgotten to apply your CSS class to the desired element. Therefore the CSS rules for that class are not going to get applied. As discussed above, you can use your browser developer tools to inspect the element's markup and then verify that the expected class is applied to the element.&lt;/p&gt;

&lt;h2&gt;
  
  
  Animation and Transition Issues
&lt;/h2&gt;

&lt;p&gt;For issues with animations and transitions, my first strategy is always to greatly slow down the timing of the animation or transition. That way I can watch as it runs, and it makes it easier to see both the start, end, and intermediate states.&lt;/p&gt;

&lt;p&gt;For animations, I also like to verify that I've specified the animation shorthand properties for time values in the right order (the first one found is set to the animation duration and the second one found is set to the animation delay).&lt;/p&gt;

&lt;p&gt;If the animation rule is crossed out, you'll know that there's likely a typo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsheelahb.com%2Fstatic%2Fced926a247ab95e3a81589cffe9d4cb4%2F93985%2Finvalid-animation.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsheelahb.com%2Fstatic%2Fced926a247ab95e3a81589cffe9d4cb4%2F93985%2Finvalid-animation.jpg" alt="An invalid animation fill mode value (forward instead of "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Another issue I've hit in the past is typos in animation keyframes which then cause the animation not to get applied. To verify the keyframes are set as expected, you can use your browser's developer tools. If you don't see the keyframes showing when inspecting the styles of the animated element like shown below, that's probably your issue:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsheelahb.com%2Fstatic%2F9c3e90a1b1068db6f274fe9ef61c7adb%2Fd5d13%2Fkeyframes.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsheelahb.com%2Fstatic%2F9c3e90a1b1068db6f274fe9ef61c7adb%2Fd5d13%2Fkeyframes.jpg" alt="Animation keyframes"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For animation debugging, I also like &lt;a href="https://css-tricks.com/debugging-css-keyframe-animations/" rel="noopener noreferrer"&gt;this CSS Tricks article by Sarah Drasner&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Hope this helps someone stuck in that "oh no, what's wrong with my CSS??!" moment.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Featured image by &lt;a href="https://unsplash.com/@markuswinkler" rel="noopener noreferrer"&gt;Markus Winkler&lt;/a&gt; via Unsplash&lt;/em&gt;.&lt;/p&gt;

</description>
      <category>css</category>
      <category>webdev</category>
    </item>
    <item>
      <title>The Pros and Cons of Headless Shopify</title>
      <dc:creator>Sheelah Brennan</dc:creator>
      <pubDate>Wed, 06 May 2020 02:51:03 +0000</pubDate>
      <link>https://dev.to/sheelah_b/the-pros-and-cons-of-headless-shopify-58ik</link>
      <guid>https://dev.to/sheelah_b/the-pros-and-cons-of-headless-shopify-58ik</guid>
      <description>&lt;p&gt;&lt;a href="https://shopify.com/"&gt;Shopify&lt;/a&gt; has become one of the big players in ecommerce, and the release of their &lt;a href="https://shopify.dev/docs/storefront-api/"&gt;Storefront API&lt;/a&gt; a few years ago opened the doors to building completely custom Shopify-based ecommerce experiences.&lt;/p&gt;

&lt;p&gt;There are pros and cons to consider when deciding whether to go with a headless Shopify ecommerce solution or a more traditional Shopify-hosted solution, and in this post I'll provide a rundown of my findings after building a React-based headless Shopify site in a recent project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Overview of Headless Shopify
&lt;/h2&gt;

&lt;p&gt;In a headless Shopify approach, you can build your own site in whatever language and framework you want and allow customers to add products to their cart, a custom cart that you've built, while still on your site. Typically the store is set up so that once the customer enters the checkout flow (typically by hitting some kind of "checkout" button), the customer is taken to your Shopify store to complete the purchase.&lt;/p&gt;

&lt;p&gt;The simplest way to build an site using this approach is to use one of the Shopify SDKs. For JavaScript-based applications, you can use the &lt;a href="https://shopify.github.io/js-buy-sdk/"&gt;Shopify Buy SDK&lt;/a&gt;. There are also SDKs for mobile. The Buy SDK uses the Shopify Storefront API under the hood and provides easy-to-use functionality for things like creating a customer checkout or fetching Shopify product data.&lt;/p&gt;

&lt;p&gt;Note that the Buy SDK does &lt;em&gt;not&lt;/em&gt; offer all of the functionality of the Storefront API. In order to access certain fields, you'll need to build a &lt;a href="https://shopify.github.io/js-buy-sdk/#expanding-the-sdk"&gt;custom Storefront API GraphQL query&lt;/a&gt;. To do this, you'll need to use the Buy SDK's unoptimized build which is quite a bit larger. For a single page app rendered client-side, this will impact page weight and overall page load times :(.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pros of Headless Shopify
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Freedom - Languages, Frameworks, and UI
&lt;/h3&gt;

&lt;p&gt;Being able to build a completely custom site and shopping experience is pretty compelling. While Shopify's cart and checkout experience has most likely gone through rigorous UI/UX design reviews, A/B testing, and lots of iterations (meaning it should be effective at leading to conversions), having the option to work closely with a UI/UX interaction designer to build a completely custom cart is a really nice option. While ecommerce is at the end of the day about sales, only you and your team know what's unique about your company and your customers. Perhaps having your own custom cart would lead to even more sales.&lt;/p&gt;

&lt;p&gt;The other advantage is in terms of tech stack. Not being tied to Shopify's templating language, &lt;a href="https://shopify.github.io/liquid/"&gt;Liquid&lt;/a&gt;, means you could your site in whatever language and using whatever framework you want, as long as it could talk to Shopify's Storefront API.&lt;/p&gt;

&lt;p&gt;If you're into Gatsby, you can use their &lt;a href="https://www.gatsbyjs.org/docs/building-an-ecommerce-site-with-shopify/"&gt;Shopify plugin&lt;/a&gt; and hit the ground running.&lt;/p&gt;

&lt;h3&gt;
  
  
  GraphQL API
&lt;/h3&gt;

&lt;p&gt;If you end up needing to use the Storefront API directly, you'll need to use GraphQL. A lot of developers are already familiar with (or are interested in building with) GraphQL-based APIs. This makes it easy to get started with if you have any level of experience with GraphQL. &lt;/p&gt;

&lt;h2&gt;
  
  
  Cons of Headless Shopify
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Non-Standard Approach Means You're Your own Support
&lt;/h3&gt;

&lt;p&gt;If something goes wrong, Shopify support likely won't be of much help. Plan on being able to and adept at troubleshooting your application on your own.&lt;/p&gt;

&lt;h3&gt;
  
  
  Roll-Your-Own Functionality
&lt;/h3&gt;

&lt;p&gt;If you cringe at the thought of building your own shopping cart, your own product options picker, or building functionality to check whether a customer checkout is stale, building a headless Shopify solution may not be the way to go. No matter what kind of site you're building, plan on at some point building some functionality that duplicates features that Shopify has out of the box. That's the tradeoff for the freedom of a headless Shopify site.&lt;/p&gt;

&lt;p&gt;Another thing you'll need to build in is support for handling any errors that the Shopify API may return, just like when dealing with any kind of API. You don't want to lose sales because of some kind of error.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cumbersome Product Metadata
&lt;/h3&gt;

&lt;p&gt;If you need to store metadata at the product or product variant level, you'll need to use Shopify &lt;a href="https://help.shopify.com/en/manual/products/metafields/"&gt;metafields&lt;/a&gt;. For example, you could use a metafield to store a shorter version of a product's name that's displayed in a shopping cart. These can become pretty cumbersome from a data entry standpoint if you have a lot of them. And you must remember to &lt;a href="https://shopify.dev/tutorials/retrieve-metafields-with-storefront-api#expose-metafields-to-the-storefront-api"&gt;whitelist all metafields&lt;/a&gt; in order to make them available to Shopify's API.&lt;/p&gt;

&lt;h3&gt;
  
  
  GraphQL API
&lt;/h3&gt;

&lt;p&gt;The GraphQL API can be considered a con for developers who are more used to JSON-based APIs. However, the Storefront API documentation is decent and there is &lt;a href="https://shopify.dev/concepts/graphql/benefits/"&gt;intro to GraphQL documentation&lt;/a&gt; as well. There is also a &lt;a href="https://shopify.dev/tools/graphiql-storefront-api/"&gt;Shopify Storefront API GraphiQL explorer tool&lt;/a&gt; that you can use to test out GraphQL queries on Shopify's demo store.&lt;/p&gt;

&lt;h3&gt;
  
  
  API Limits
&lt;/h3&gt;

&lt;p&gt;There are &lt;a href="https://shopify.dev/docs/storefront-api/getting-started#storefront-api-rate-limits/"&gt;Storefront API rate limits&lt;/a&gt; to take into account when building a headless Shopify site. Luckily, these limits do take a user's IP address into account, so surges in traffic (Ex. due to a product launch) shouldn't put your app at risk of hitting up against these limits. Note that if you're on Shopify Plus, the limits are higher.&lt;/p&gt;

&lt;h3&gt;
  
  
  Less Availability of Add-On Apps
&lt;/h3&gt;

&lt;p&gt;If you're used to being able to install add-ons to add new functionality (like you can with Shopify and with CMSs like WordPress), you'll be mostly out of luck. With headless Shopify, add-ons that you use on the backend side (within Shopify's admin interface, for example), will usually work fine. But add-ons that rely on you having a Shopify theme will not.&lt;/p&gt;

&lt;h3&gt;
  
  
  Less-Than-Stellar Image Tooling
&lt;/h3&gt;

&lt;p&gt;If you're used to frameworks like Gatsby that handle image optimization for you, you're going to be more DIY under headless Shopify. There are some image helpers in Shopify's Github repo that can help you crop images, but there is nothing available that does image transformations for you like &lt;a href="https://www.cloudinary.com/"&gt;Cloudinary&lt;/a&gt; or &lt;a href="https://www.imgix.com/"&gt;Imgix&lt;/a&gt;. You will have access to Shopify's CDN for images, but other than that you're on your own. What you can do is look for other image tools that work on top of Shopify.&lt;/p&gt;

&lt;p&gt;While it's likely not officially supported or endosed by Shopify, Imgix does work as a layer on top of Shopify. That would allow you to do things like image cropping, filters, etc. The only caveat is that if you want to replace an image in Shopify you'll need to make sure to rename the file before re-uploading it. The reason is that Shopify doesn't currently have a way to let you purge their CDN cache for a single image URL like Imgix does. Maybe someday! I put in a feature request :-).&lt;/p&gt;

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

&lt;p&gt;There's a lot to consider on both sides of this, and I hope this helps someone out there who's looking into Headless Shopify. Have you built a headless Shopify site? I'd love to hear what you built it with and how it worked out.&lt;/p&gt;

&lt;p&gt;Featured image by &lt;a href="https://unsplash.com/@theburbgirl"&gt;Lauren Fleischmann&lt;/a&gt; via Unsplash&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>javascript</category>
      <category>shopify</category>
    </item>
    <item>
      <title>Add Visual Interest to Your Website/Web App</title>
      <dc:creator>Sheelah Brennan</dc:creator>
      <pubDate>Tue, 17 Sep 2019 18:18:13 +0000</pubDate>
      <link>https://dev.to/sheelah_b/add-visual-interest-to-your-website-web-app-43f0</link>
      <guid>https://dev.to/sheelah_b/add-visual-interest-to-your-website-web-app-43f0</guid>
      <description>&lt;p&gt;My Skillshare course on making your website/web app stand out (using HTML, CSS, and SVG) went live today &amp;amp; I'm launching it as a free course! You'll just need a free Skillshare &amp;amp; CodePen account.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://skl.sh/2kr2xrq"&gt;https://skl.sh/2kr2xrq&lt;/a&gt; &lt;/p&gt;

</description>
      <category>courses</category>
      <category>css</category>
      <category>svg</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
