<?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>Forem: Dmytro</title>
    <description>The latest articles on Forem by Dmytro (@dmytrych).</description>
    <link>https://forem.com/dmytrych</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%2F1088109%2F360dad94-aad4-41ef-95a9-ae076505f80d.jpeg</url>
      <title>Forem: Dmytro</title>
      <link>https://forem.com/dmytrych</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/dmytrych"/>
    <language>en</language>
    <item>
      <title>ReactJS: infinite scroll using IntersectionObserver</title>
      <dc:creator>Dmytro</dc:creator>
      <pubDate>Sun, 16 Jul 2023 10:25:43 +0000</pubDate>
      <link>https://forem.com/dmytrych/implementing-infinite-scroll-in-a-react-app-using-intersectionobserver-f6h</link>
      <guid>https://forem.com/dmytrych/implementing-infinite-scroll-in-a-react-app-using-intersectionobserver-f6h</guid>
      <description>&lt;p&gt;&lt;a href="http://devcenter.space/uk/posts/react-intersection-observer-infinite-scroll/" rel="noopener noreferrer"&gt;Ukrainian translation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this guide, we'll be creating an infinite scroll feature in a React app using the &lt;code&gt;IntersectionObserver&lt;/code&gt; API, which currently is one of the easiest ways of implementing an adaptive infinite scroll component without any libraries like &lt;code&gt;react-scroll&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Initial Setup
&lt;/h2&gt;

&lt;p&gt;Assuming you already have a React project setup, we will start by creating a new component, let's call it &lt;code&gt;InfiniteScroll&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&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;InfiniteScroll&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&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;Infinite Scroll Component&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;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;InfiniteScroll&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Implementing Infinite Scroll with IntersectionObserver
&lt;/h2&gt;

&lt;p&gt;In the &lt;code&gt;InfiniteScroll&lt;/code&gt; component, we need to initialize our &lt;code&gt;IntersectionObserver&lt;/code&gt; and attach it to a &lt;code&gt;marker&lt;/code&gt; element that will be observed.&lt;/p&gt;

&lt;p&gt;Whenever our marker comes into view, our callback will be fired, and we can fetch more data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useRef&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&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;InfiniteScroll&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;fetchMoreData&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;marker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRef&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="nf"&gt;useEffect&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;observer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;IntersectionObserver&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;isIntersecting&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;fetchMoreData&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;marker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;observer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;observe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;marker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="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;gt;&lt;/span&gt; &lt;span class="nx"&gt;observer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;disconnect&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="k"&gt;return &lt;/span&gt;&lt;span class="p"&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;Infinite Scroll Component&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;div&lt;/span&gt; &lt;span class="na"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;marker&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Loading...&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;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;InfiniteScroll&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;In the above code, we have added a new &lt;code&gt;div&lt;/code&gt; with a &lt;code&gt;ref&lt;/code&gt; of &lt;code&gt;marker&lt;/code&gt;. This is the element we'll be observing with our &lt;code&gt;IntersectionObserver&lt;/code&gt;. When this element comes into the viewport, our callback will fire and call the &lt;code&gt;fetchMoreData&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;fetchMoreData&lt;/code&gt; function should be a function that fetches more data and appends it to your current list of data.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to solve the repeating data problem?
&lt;/h2&gt;

&lt;p&gt;You may have faced an issue that you keep loading the same page of data each time more data is loaded. This is caused by the &lt;code&gt;fetchMoreData&lt;/code&gt; function being locked inside of the expression, which is passed inside &lt;code&gt;IntersectionObserver&lt;/code&gt;. This means that this expression uses the version of &lt;code&gt;fetchMoreData&lt;/code&gt; which was created on the very first render of the page, and it is not changed afterwards.&lt;/p&gt;

&lt;p&gt;To fix this - you need to provide a fresh value of the &lt;code&gt;fetchMoreData&lt;/code&gt; function each time it is called. It can easily be reached with using &lt;code&gt;useRef&lt;/code&gt; hook.&lt;/p&gt;

&lt;p&gt;Modify your code to look similar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useRef&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&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;InfiniteScroll&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;fetchMoreData&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;marker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRef&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;fetchMoreDataRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRef&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fetchMoreData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nf"&gt;useEffect&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;observer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;IntersectionObserver&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;isIntersecting&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;fetchMoreDataRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;current&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;marker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;observer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;observe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;marker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="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;gt;&lt;/span&gt; &lt;span class="nx"&gt;observer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;disconnect&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="k"&gt;return &lt;/span&gt;&lt;span class="p"&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;Infinite Scroll Component&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;div&lt;/span&gt; &lt;span class="na"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;marker&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Loading...&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;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;InfiniteScroll&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;By passing the &lt;code&gt;fetchMoreData&lt;/code&gt; into &lt;code&gt;useRef&lt;/code&gt;, we made its value to be updated, with the fresh &lt;code&gt;current&lt;/code&gt; value all the time. This means that when the &lt;code&gt;IntersectionObserver&lt;/code&gt; calls &lt;code&gt;fetchMoreDataRef.current()&lt;/code&gt; - it calls the latest value of the function, which triggers loading of the &lt;strong&gt;new&lt;/strong&gt; page of data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Drawbacks of using an IntersectionObserver for infinite scroll implementation
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Performance Issues:&lt;/strong&gt; If not implemented correctly, infinite scrolling can cause performance issues. As more and more content is loaded and added to the DOM, the website can become slow and unresponsive over time. Therefore, it's essential to implement some sort of cleanup or "virtual scrolling" where off-screen elements are removed from the DOM.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;SEO Challenges:&lt;/strong&gt; Infinite scroll can be a challenge for SEO. Search engines traditionally crawl websites by following links and may not be able to fully index content that is loaded via infinite scroll. However, this can be mitigated by providing a traditional pagination fallback for search engine crawlers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;User Navigation:&lt;/strong&gt; Infinite scroll can make it difficult for users to reach the footer of your page. If important links or information are located there, users might never see them because new content keeps loading. A potential solution can be to have a static footer or include important links elsewhere.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Browser Compatibility:&lt;/strong&gt; &lt;code&gt;IntersectionObserver&lt;/code&gt; is not supported in all browsers, although support is now widespread and includes all modern browsers. However, if you're developing an app that needs to support older browsers, this could be a significant drawback.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Remember, these are potential drawbacks, but many of them can be mitigated with careful planning and good implementation practices. The correct use of the &lt;code&gt;IntersectionObserver&lt;/code&gt; API for infinite scroll really depends on your specific application and user needs.&lt;/p&gt;

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

&lt;p&gt;We have explored how to create an infinite scroll feature in a React application using the &lt;code&gt;IntersectionObserver&lt;/code&gt; API. By initializing an &lt;code&gt;IntersectionObserver&lt;/code&gt; and linking it to a designated &lt;code&gt;marker&lt;/code&gt; element, we've seen how we can progressively load more content as the user scrolls, providing a seamless user experience.&lt;/p&gt;

&lt;p&gt;We have also addressed a common issue regarding the inadvertent reloading of the same data page by encapsulating our data fetching function (&lt;code&gt;fetchMoreData&lt;/code&gt;) within a &lt;code&gt;useRef&lt;/code&gt; hook. This solution ensures we always reference the latest iteration of our function, enabling us to load new pages of data consistently.&lt;/p&gt;

&lt;p&gt;While the &lt;code&gt;IntersectionObserver&lt;/code&gt; API provides an effective and straightforward solution, it's essential to remember that more complex apps may require more sophisticated error handling and optimization. The principles outlined here, however, will lay a solid foundation for creating an efficient and user-friendly infinite scroll feature.&lt;/p&gt;

&lt;p&gt;As you implement these strategies in your applications, you'll be well on your way to creating a more immersive, engaging user experience that keeps your audience scrolling for more. Happy coding!&lt;/p&gt;

&lt;p&gt;Find more interesting articles about JavaScript development &lt;a href="https://devcenter.space/" rel="noopener noreferrer"&gt;On my personal website&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also, it has &lt;a href="http://devcenter.space/uk/" rel="noopener noreferrer"&gt;ukrainian translation&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>tutorial</category>
      <category>react</category>
    </item>
    <item>
      <title>MongoDB: Query Writing With ChatGPT</title>
      <dc:creator>Dmytro</dc:creator>
      <pubDate>Mon, 03 Jul 2023 13:56:00 +0000</pubDate>
      <link>https://forem.com/dmytrych/how-to-write-mongodb-queries-using-chatgpt-no6</link>
      <guid>https://forem.com/dmytrych/how-to-write-mongodb-queries-using-chatgpt-no6</guid>
      <description>&lt;p&gt;&lt;a href="https://devcenter.space/uk/posts/querying-mongodb-with-chatgpt/" rel="noopener noreferrer"&gt;Ukrainian translation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Writing effective MongoDB queries can be a complex task, requiring a deep understanding of the database's query language. However, with ChatGPT, an advanced language model developed by OpenAI, crafting accurate and efficient MongoDB queries becomes more accessible. In this article, we'll explore how ChatGPT's natural language processing capabilities can assist developers in formulating MongoDB queries through a conversational interface. By the end, you'll have the knowledge and tools to streamline your MongoDB querying process and unlock new possibilities for extracting meaningful insights from your data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Should I use ChatGPT for Writing MongoDB Queries?
&lt;/h2&gt;

&lt;p&gt;The complexity of the database's query language and the need for a deep understanding of its syntax and structure can make it difficult for developers to write queries accurately, especially for the beginners.&lt;/p&gt;

&lt;p&gt;Writing queries with ChatGPT can significantly speed up the process of writing and debugging, due to the following reasons:&lt;/p&gt;

&lt;h3&gt;
  
  
  Instant and accurate generation of simple queries
&lt;/h3&gt;

&lt;p&gt;Even the simplest MongoDB query can take a lot of time for debugging and finding the correct query operator. However, it is quite easy for ChatGPT to turn your words into the working query.&lt;/p&gt;

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

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

&lt;h3&gt;
  
  
  Automatic Performance Optimization
&lt;/h3&gt;

&lt;p&gt;You can ask ChatGPT to automatically optimize the queries it generates. The more info you provide to him - the better optimization will be. However, even providing info about MongoDB collection indexes can benefit the generated queries.&lt;/p&gt;

&lt;p&gt;For example, it can provide the following query:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

db.products.find({ category: "Electronics" }).sort({ price: -1 })


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

&lt;/div&gt;

&lt;p&gt;However, it can automatically generate the query which enforces using the index for your query.&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

&lt;p&gt;db.products.find({ category: "Electronics" }).sort({ price: -1 }).hint({ category: 1, price: -1 })&lt;/p&gt;

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

&lt;/div&gt;
&lt;h3&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Easier Query Debugging and Rewriting&lt;br&gt;
&lt;/h3&gt;

&lt;p&gt;If you face any problems in debugging the query, ChatGPT can easily detect and fix the issue, even if it requires major changes. At the same time, fixing queries yourself can cause multiple new bugs and will take much more time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tips For Writing MongoDB Queries With ChatGPT
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Provide as much necessary info, as you can
&lt;/h3&gt;

&lt;p&gt;If you are going to write a complex and heavily optimized query - provide ChatGPT with a full model, if possible. Give it information about your MongoDB collection indexes, or any other nuances it should know, to perform its job.&lt;/p&gt;

&lt;p&gt;If you write queries really often - create a template message with this info, so you can quickly paste it, and begin working immediately.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ask ChatGPT to remove explanation from results.
&lt;/h3&gt;

&lt;p&gt;Asking the AI, to remove explanations can significantly increase the speed of the generation (especially in the free version), and will not make your chat too long, so it will be easier to find old queries if you will need them.&lt;/p&gt;

&lt;p&gt;To remove explanations - provide it with the following message: "I am going to ask you to write mongodb queries. Provide me only the queries I asked you for, wrapped in code block. I do not want you to send anything else in the response. If you understood, give me the query wich will get product with field "name" equal to "Hello World". It should not contain any explanations, as I asked."&lt;/p&gt;

&lt;p&gt;Result:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb3le8hz3p581q2bahohl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb3le8hz3p581q2bahohl.png" alt="Asking Chat not to provide explanations for generated mongodb query"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Do not provide sensitive information to ChatGPT
&lt;/h3&gt;

&lt;p&gt;Remember, the &lt;strong&gt;ChatGPT IS NOT CONFIDENTIAL&lt;/strong&gt;. Never provide ChatGPT with any passwords/keys/users personal information. Even if it seems like nobody sees your queries - it doesn't mean that the message you write will not be used for training, or will not be viewed by one of the OpenAI data engineers. Moreover, the sensitive data can leak even through hackers reading your message history.&lt;/p&gt;

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

&lt;p&gt;In conclusion, using ChatGPT can greatly simplify the process of writing MongoDB queries by leveraging its natural language processing capabilities. With instant query generation, automatic performance optimization, and easy query debugging and rewriting, developers can streamline their workflow and save time. By providing necessary information and removing explanations from results, developers can enhance the efficiency of their interactions with ChatGPT. However, it's important to note that sensitive information should never be shared with ChatGPT, as it is not confidential.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://devcenter.space/" rel="noopener noreferrer"&gt;More Interesting Articles&lt;/a&gt;&lt;/p&gt;

</description>
      <category>mongodb</category>
      <category>javascript</category>
      <category>chatgpt</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Fixing Prettier not working with VSCode</title>
      <dc:creator>Dmytro</dc:creator>
      <pubDate>Fri, 09 Jun 2023 06:49:46 +0000</pubDate>
      <link>https://forem.com/dmytrych/fixing-prettier-not-working-with-vscode-44ml</link>
      <guid>https://forem.com/dmytrych/fixing-prettier-not-working-with-vscode-44ml</guid>
      <description>&lt;p&gt;&lt;a href="https://devcenter.space/uk/posts/prettier-vscode-problems/" rel="noopener noreferrer"&gt;Ukrainian version&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Problem Description
&lt;/h2&gt;

&lt;p&gt;You have installed and enabled Prettier in your JS application, but Visual Studio Code does not format or highlight your code.&lt;/p&gt;

&lt;p&gt;If you have not yet installed Prettier in your application - you can see the guide for its installation &lt;a href="https://devcenter.space/posts/prettier-setup/" rel="noopener noreferrer"&gt;at the link&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Ways of Fixing:
&lt;/h2&gt;

&lt;p&gt;There are several possible problems that can occur with code analysis. Here are the main ones:&lt;/p&gt;

&lt;h3&gt;
  
  
  Prettier is Not Installed
&lt;/h3&gt;

&lt;p&gt;Check your &lt;code&gt;package.json&lt;/code&gt; for the Prettier version installed:&lt;/p&gt;

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

&lt;p&gt;If prettier is installed, try running &lt;code&gt;npm install&lt;/code&gt;, just in case.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prettier Extension in VSCode is Not Installed
&lt;/h3&gt;

&lt;p&gt;Make sure you have installed the Prettier extension in VSCode. If it is missing, you can find it at the link: &lt;a href="https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode" rel="noopener noreferrer"&gt;https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Invalid or Missing Configuration File
&lt;/h3&gt;

&lt;p&gt;Check that the &lt;code&gt;.prettierrc&lt;/code&gt; or &lt;code&gt;prettier.config.js&lt;/code&gt; file is present and correct.&lt;/p&gt;

&lt;p&gt;Try replacing your configuration file with another, verified file. You can use the basic config from the documentation:&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&lt;br&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"trailingComma"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"es5"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;br&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"tabWidth"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;br&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"semi"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;&lt;br&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"singleQuote"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;&lt;br&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;h3&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Prettier is Not Set as a Default Code Formatter&lt;br&gt;
&lt;/h3&gt;

&lt;p&gt;Go to &lt;code&gt;File -&amp;gt; Preferences -&amp;gt; Settings&lt;/code&gt; or (&lt;code&gt;Ctrl&lt;/code&gt; + &lt;code&gt;comma&lt;/code&gt;). And do a search on the word &lt;code&gt;formatter&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In the opened tab, select 'Default Formatter' - `Prettier'.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Disabled File Extensions or Incorrect Language Configurations
&lt;/h3&gt;

&lt;p&gt;Prettier can be configured to disable parsing for certain file types - so check that the required files are not included in the &lt;code&gt;prettier-ignore&lt;/code&gt; file.&lt;br&gt;
Also, check that your file extension is spelled correctly.&lt;/p&gt;

&lt;p&gt;Also, make sure that the settings correspond to the programming language you are using.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conflicting VSCode Extensions
&lt;/h3&gt;

&lt;p&gt;Try disabling other VSCode extensions. Conflicting extensions can interfere with Prettier.&lt;/p&gt;

&lt;h3&gt;
  
  
  Obsolete Prettier version
&lt;/h3&gt;

&lt;p&gt;Newer versions of VSCode extensions may not support older versions of Prettier. If necessary, raise the Prettier version in &lt;code&gt;package.json&lt;/code&gt;.&lt;/p&gt;

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

&lt;p&gt;In this article, we looked at possible problems with the integration of Prettier and VSCode. I hope that these tips will help you solve the problems you encountered.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using Prettier with ESLint? See also:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://devcenter.space/posts/eslint-rules-vs-plugins/" rel="noopener noreferrer"&gt;Difference between Plugins and ESLint Rules&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devcenter.space/posts/eslint-best-practices/" rel="noopener noreferrer"&gt;Mastering ESLint Configurations: Best Practices&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://devcenter.space/" rel="noopener noreferrer"&gt;More interesting articles&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>vscode</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
    <item>
      <title>ESLint: Правила чи Плагіни?</title>
      <dc:creator>Dmytro</dc:creator>
      <pubDate>Mon, 05 Jun 2023 12:39:23 +0000</pubDate>
      <link>https://forem.com/dmytrych/pravila-ta-plaghini-v-eslint-4113</link>
      <guid>https://forem.com/dmytrych/pravila-ta-plaghini-v-eslint-4113</guid>
      <description>&lt;p&gt;&lt;strong&gt;Find this and other articles in English:&lt;/strong&gt; &lt;a href="https://devcenter.space/posts/eslint-rules-vs-plugins/" rel="noopener noreferrer"&gt;https://devcenter.space/posts/eslint-rules-vs-plugins/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ESlint - це потужний інструмент для перевірки якості коду в проектах JavaScript. Однак, два основних поняття, з якими стикаються користувачі ESlint, - це "правила" та "плагіни". Давайте розберемося у відмінностях між ними.&lt;/p&gt;

&lt;h2&gt;
  
  
  Правила (Rules)
&lt;/h2&gt;

&lt;p&gt;Правила в ESlint - це набір правил, які визначають правильний або неправильний стиль написання коду. Вони допомагають виявити потенційні проблеми в коді та стильові недоліки, такі як відсутність крапки з комою, використання неоголошених змінних, використання заборонених функцій тощо. ESlint має вбудований набір правил, які можна використовувати за замовчуванням. Проте, ви також можете налаштовувати правила згідно з власними потребами.&lt;/p&gt;

&lt;p&gt;Наприклад, ось декілька прикладів правил:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;semi&lt;/code&gt; - це правило вимагає використовувати крапку з комою в кінці кожного оператора.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;no-console&lt;/code&gt; - це правило забороняє використання функції &lt;code&gt;console.log()&lt;/code&gt; та інших методів &lt;code&gt;console&lt;/code&gt; у продакшн-коді.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Плагіни (Plugins)
&lt;/h2&gt;

&lt;p&gt;Плагіни в ESlint - це додаткові модулі, які дозволяють розширити функціональність ESlint. Вони надають додаткові правила та можливості перевірки коду, які не включені в основний набір правил. Плагіни можуть бути розроблені спільнотою ESlint або створені вами самостійно. Щоб використовувати плагін, спочатку потрібно його встановити через менеджер пакетів, такий як npm або yarn.&lt;/p&gt;

&lt;p&gt;Наприклад, плагін &lt;code&gt;eslint-plugin-react&lt;/code&gt; - це популярний плагін для перевірки React коду&lt;/p&gt;

&lt;h2&gt;
  
  
  Висновок
&lt;/h2&gt;

&lt;p&gt;Правила та плагіни є важливими складовими ESlint. Правила допомагають забезпечити правильний стиль коду та виявити потенційні проблеми, тоді як плагіни дозволяють розширити функціональність ESlint та використовувати специфічні правила для конкретних технологій або фреймворків. З правильним налаштуванням правил та використанням плагінів, ви можете покращити якість свого коду та забезпечити більш однорідний стиль розробки.&lt;/p&gt;

&lt;h2&gt;
  
  
  Дізнайтеся більше
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Як встановити ESlint: &lt;a href="https://devcenter.space/uk/posts/eslint-setup/" rel="noopener noreferrer"&gt;посилання&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Oфіційна документація ESlint: &lt;a href="https://eslint.org/docs/latest/" rel="noopener noreferrer"&gt;посилання&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://devcenter.space/" rel="noopener noreferrer"&gt;Більше цікавих статей&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
    <item>
      <title>SEO: hreflang attribute for content with multiple translations</title>
      <dc:creator>Dmytro</dc:creator>
      <pubDate>Sat, 03 Jun 2023 18:26:49 +0000</pubDate>
      <link>https://forem.com/dmytrych/seo-for-localized-content-hreflang-attribute-32fp</link>
      <guid>https://forem.com/dmytrych/seo-for-localized-content-hreflang-attribute-32fp</guid>
      <description>&lt;p&gt;Read this article in ukrainian: &lt;a href="https://devcenter.space/uk/posts/how-to-setup-hreflang/" rel="noopener noreferrer"&gt;https://devcenter.space/uk/posts/how-to-setup-hreflang/&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a hreflang Attribute?
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;hreflang&lt;/code&gt; attribute is a part of the HTML tag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;link rel="alternate" href="https://example.com" hreflang="uk-ua" /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The presence of this tag means that the page on which it is placed &lt;strong&gt;has translations in other languages&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This tag is intended to facilitate the indexing of your site by search engines. Google uses "hreflang" to determine which version of the page to suggest to the user.&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding the hreflang
&lt;/h3&gt;

&lt;p&gt;For example, you have a website localized in two languages: the main language - &lt;strong&gt;Ukrainian&lt;/strong&gt;, and an additional one - &lt;strong&gt;English&lt;/strong&gt;. In this case, your &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; tag should contain the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;head&amp;gt;
  ...
  &amp;lt;link rel="alternate" hrefLang="en" href={`https://example.com/en`} /&amp;gt;
  &amp;lt;link rel="alternate" hrefLang="uk-UA" href={`https://example.com/uk`} /&amp;gt;
  &amp;lt;link rel="alternate" hrefLang="x-default" href={`https://example.com`} /&amp;gt;
  ...
&amp;lt;/head&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, &lt;code&gt;hrefLang&lt;/code&gt; attributes contain locale names.&lt;/p&gt;

&lt;p&gt;Look at the &lt;code&gt;hreflang&lt;/code&gt; value for the Ukrainian localization: in addition to the translation language value, it also has the specified region "UA". Thus, for another region, you can create your own localization in this language. However, if the region is not important - it can be omitted, for example, both users from "en-NZ" and from "en-US" will get to the "en" locale.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;x-default&lt;/code&gt; value will be used by the search engine if the user's locale does not match any of the listed ones. Then the page specified in the tag with &lt;code&gt;x-default&lt;/code&gt; will be returned to the user.&lt;/p&gt;

&lt;h3&gt;
  
  
  Href Attribute Value
&lt;/h3&gt;

&lt;p&gt;There is a nuance related to the value of the &lt;code&gt;href&lt;/code&gt; attribute - the link to the localized page &lt;strong&gt;must be absolute&lt;/strong&gt;, along with &lt;code&gt;https://&lt;/code&gt; and the domain name. Google will &lt;strong&gt;not accept&lt;/strong&gt; links &lt;code&gt;example.com/en&lt;/code&gt;, &lt;code&gt;/en&lt;/code&gt; and others.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Mistakes
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Make sure that each version of the page has a return link to all available localization options.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Suppose we have two versions of the same page, in languages X and Y. It follows that page X should have &lt;code&gt;link&lt;/code&gt; tags with "hreflang=X" and "hreflang=Y".&lt;/p&gt;

&lt;p&gt;Page Y must have identical &lt;code&gt;hreflang&lt;/code&gt;, too. If page Y does not have, for example, `hreflang=X', then Google will refuse to index it.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Check that you have entered the values exactly in &lt;a href="https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes" rel="noopener noreferrer"&gt;ISO_639-1&lt;/a&gt; format. Localization names in this standard differ from country codes. As an example, you may have already noticed that the "uk" localization means the Ukrainian localization. The British localization is indicated as "gb".&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The specified locale "hreflang" must match the value specified in the &lt;code&gt;&amp;lt;html lang=""&amp;gt;&lt;/code&gt; tag. The value of this attribute should change with localization.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Not specified or invalid &lt;code&gt;x-default&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The specified relative, not the absolute value of &lt;code&gt;href&lt;/code&gt;. Only links of the format "&lt;a href="https://example.com/en" rel="noopener noreferrer"&gt;https://example.com/en&lt;/a&gt;" will be valid, not "example.com/en" or "/en".&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  How to Check the Validity of the hreflang on Your Website?
&lt;/h3&gt;

&lt;p&gt;For automatic analysis of errors related to localization, I recommend the site &lt;a href="https://technicalseo.com/tools/hreflang/" rel="noopener noreferrer"&gt;https://technicalseo.com/tools/hreflang/&lt;/a&gt;. Although you can find more similar services by searching on Google.&lt;/p&gt;

&lt;p&gt;More articles in my personal blog: &lt;a href="https://devcenter.space/" rel="noopener noreferrer"&gt;https://devcenter.space/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>beginners</category>
      <category>seo</category>
      <category>programming</category>
    </item>
    <item>
      <title>ESLint: How to install and configure?</title>
      <dc:creator>Dmytro</dc:creator>
      <pubDate>Thu, 01 Jun 2023 07:20:21 +0000</pubDate>
      <link>https://forem.com/dmytrych/eslint-how-to-install-and-configure-9n9</link>
      <guid>https://forem.com/dmytrych/eslint-how-to-install-and-configure-9n9</guid>
      <description>&lt;p&gt;Read this article in ukrainian: &lt;a href="https://devcenter.space/uk/posts/eslint-setup/" rel="noopener noreferrer"&gt;https://devcenter.space/uk/posts/eslint-setup/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Read more articles about ESLint in my personal blog: &lt;a href="https://devcenter.space/" rel="noopener noreferrer"&gt;https://devcenter.space/&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is ESLint?
&lt;/h2&gt;

&lt;p&gt;ESLint is a linter for NodeJS applications. Its purpose is to automatically detect potential problems in your code. Linters, and ESLint in particular, can identify not only problems in code formatting, but also see potential bugs, problems in operation, gaps in the security of your application.&lt;/p&gt;

&lt;p&gt;This is what makes ESLint different from the code formatting tool, Prettier, which can only find and fix code style issues, but won't tell you if your code contains an error. Prettier can be used in combination with ESLint to promote code styles. More about how to install Prettier - (&lt;a href="https://devcenter.space/posts/prettier-setup/" rel="noopener noreferrer"&gt;in a separate article&lt;/a&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;p&gt;In order to automatically install ESLint and add all the necessary files for work, it is enough to write the following command in the terminal:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

npm init @eslint/config


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

&lt;/div&gt;

&lt;p&gt;After entering the command, you will be asked which ESLint feature you plan to use. The selection is made with the keyboard arrows, and the selection window itself looks like this:&lt;/p&gt;

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

&lt;p&gt;Based on your selection, the linter settings will be selected.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuration process
&lt;/h2&gt;

&lt;p&gt;There is no point in describing the full process at this time, but I would like to draw your attention to a few points:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"How would you like to define a style for your project?"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this option, I advise you to choose the &lt;code&gt;guide&lt;/code&gt; option if you are setting up ESLint for the first time. Any settings you need can be changed after installation whenever you need.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"Which style guide do you want to follow?"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Again, for the first time I advise you to set &lt;code&gt;Standard&lt;/code&gt;, and change if necessary.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"What format do you want your config file to be in?"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here you can choose any of the formats. But I would like to emphasize that most articles on the Internet use the JSON format. This article will be no exception.&lt;/p&gt;

&lt;p&gt;After the installation process, a &lt;code&gt;.eslintrc.*&lt;/code&gt; file with the selected extension should appear in your project.&lt;/p&gt;

&lt;p&gt;My &lt;code&gt;.eslintrc.json&lt;/code&gt; looks like this:&lt;/p&gt;

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

&lt;h2&gt;
  
  
  ESLint plugins
&lt;/h2&gt;

&lt;p&gt;ESLint, in addition to the standard set of rules, has an interface for installing add-ons (plugins) into your project. In order to use a custom plugin, you need to install it via npm/yarn, and then add the plugin to the &lt;code&gt;plugins&lt;/code&gt; list.&lt;/p&gt;

&lt;p&gt;An example of setting up the Prettier plugin for ESLint can be seen in &lt;a href="https://devcenter.space/posts/prettier-setup/" rel="noopener noreferrer"&gt;the previous article&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Useful plugins for ESLint &lt;a href="https://github.com/dustinspecker/awesome-eslint#plugins" rel="noopener noreferrer"&gt;found here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  IDE support
&lt;/h2&gt;

&lt;p&gt;Some IDEs require additional configuration to enable ESLint error highlighting in the editor. Plugins or guides for configuring ESLint for popular IDEs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint" rel="noopener noreferrer"&gt;Visual Studio Code&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.jetbrains.com/help/webstorm/eslint.html#ws_js_eslint_activate" rel="noopener noreferrer"&gt;WebStorm&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://packagecontrol.io/packages/ESLint" rel="noopener noreferrer"&gt;Sublime Text&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://vimawesome.com/plugin/eslint" rel="noopener noreferrer"&gt;Vim&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hackernoon.com/set-up-eslint-in-atom-83dfb3d34fdf" rel="noopener noreferrer"&gt;Atom&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;ESLint is a linter for NodeJS applications with extensive functionality that will help you monitor compliance with code styles in your project, help you find potential bugs or syntax errors. ESLint can be configured quite flexibly by point-editing its rules and installing external add-ons. ESLint has integration with an extensive list of development environments.&lt;/p&gt;

&lt;h2&gt;
  
  
  Read more about ESLint
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;ESLint best practices: &lt;a href="https://devcenter.space/posts/eslint-best-practices/" rel="noopener noreferrer"&gt;link&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;How to create a balanced ESLint config: &lt;a href="https://devcenter.space/posts/eslint-rule-balance/" rel="noopener noreferrer"&gt;link&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Difference between ESLint Plugins and Rules: &lt;a href="https://devcenter.space/posts/eslint-rules-vs-plugins/" rel="noopener noreferrer"&gt;link&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Official documentation: &lt;a href="https://eslint.org/docs/latest/" rel="noopener noreferrer"&gt;link&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://devcenter.space/" rel="noopener noreferrer"&gt;More articles&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>tutorial</category>
      <category>programming</category>
    </item>
    <item>
      <title>ESLint Configuration: Strictness vs Flexibility</title>
      <dc:creator>Dmytro</dc:creator>
      <pubDate>Mon, 29 May 2023 06:01:14 +0000</pubDate>
      <link>https://forem.com/dmytrych/eslint-rule-configuration-striking-the-balance-between-strictness-and-flexibility-1i5i</link>
      <guid>https://forem.com/dmytrych/eslint-rule-configuration-striking-the-balance-between-strictness-and-flexibility-1i5i</guid>
      <description>&lt;p&gt;An article from my personal blog: &lt;a href="https://devcenter.space/" rel="noopener noreferrer"&gt;https://devcenter.space/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ESLint is a powerful tool for enforcing coding standards and catching potential errors in JavaScript code. When configuring ESLint rules, finding the right balance between strictness and flexibility is crucial. Overly strict rules can lead to an overwhelming number of linting errors, while being too lenient may allow problematic code to slip through. In this article, we will explore strategies for striking the ideal balance in ESLint rule configuration to ensure code quality while maintaining developer productivity.&lt;/p&gt;

&lt;p&gt;If you still don't have the ESLint in your project - check out the &lt;a href="https://devcenter.space/posts/eslint-setup/" rel="noopener noreferrer"&gt;ESLint installation guide&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Understand Your Project's Requirements
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffzxhh2bc79p7d9kwewtr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffzxhh2bc79p7d9kwewtr.png" alt="Who? When? Where? When? Why? How? Requirements" width="800" height="200"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before configuring ESLint rules, it's important to understand your project's specific requirements and coding style. Consider factors such as the project's size, complexity, team dynamics, and targeted audience. A project with a large team or strict code review process might benefit from more strict rules, while a small project or prototype might prioritize flexibility to iterate quickly. Understanding the project context will guide your decision-making process.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Start with a Sensible Baseline Configuration
&lt;/h2&gt;

&lt;p&gt;To strike the initial balance, start with a sensible baseline configuration such as &lt;code&gt;eslint:recommended&lt;/code&gt; or a popular shareable configuration. These configurations are widely accepted and cover many best practices. They provide a solid foundation to ensure code quality without overwhelming developers with excessive rule violations. Starting with a baseline allows you to fine-tune rules based on your project's needs.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Customize Rules for Your Project
&lt;/h2&gt;

&lt;p&gt;Every project has its unique set of requirements and coding style preferences. Customize ESLint rules to align with your project's specific needs. Enable rules that enforce coding standards relevant to your project while disabling rules that may conflict with your chosen coding style or cause excessive noise. Strike a balance between enforcing best practices and allowing developers the flexibility to work efficiently.&lt;/p&gt;

&lt;p&gt;How to customize your ESLint rules: &lt;a href="https://eslint.org/docs/latest/use/configure/rules" rel="noopener noreferrer"&gt;Official Documentation Link&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Gradually Increase Strictness
&lt;/h2&gt;

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

&lt;p&gt;Striving for perfection from the start may hinder productivity and create resistance from the development team. Instead, consider gradually increasing the strictness of ESLint rules over time. Begin with a conservative configuration that catches critical issues and gradually add more rules as the team becomes accustomed to the linting process. This incremental approach helps developers embrace linting while maintaining a balance between productivity and code quality.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Leverage Rule Severity Levels
&lt;/h2&gt;

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

&lt;p&gt;ESLint rules have severity levels: "off," "warn," and "error." Use these levels strategically to fine-tune the balance between strictness and flexibility. Consider assigning the "warn" severity to rules that catch potential issues or deviations from coding standards, allowing developers to address them at their discretion. Reserve the "error" severity for critical issues that must be fixed before the code can be considered valid. This approach ensures flexibility while highlighting important issues.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Collaborate with the Development Team
&lt;/h2&gt;

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

&lt;p&gt;ESLint rule configuration should be a collaborative effort involving the development team. Encourage discussions and feedback regarding the rules and their impact on productivity. Conduct regular meetings or open channels for developers to express their concerns or suggest rule adjustments. By involving the team, you can foster a sense of ownership and consensus on the linting rules, leading to a more balanced and effective configuration.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Regularly Evaluate and Refine Rules
&lt;/h2&gt;

&lt;p&gt;Maintaining the balance between strictness and flexibility requires regular evaluation and refinement of the ESLint rules. As the project evolves and coding standards mature, review the rules periodically. Seek feedback from the development team and consider adjustments based on the project's needs. Keep up to date with new ESLint releases and rule updates to take advantage of improved best practices and adapt to changing coding standards.&lt;/p&gt;

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

&lt;p&gt;In conclusion, achieving the right balance between strictness and flexibility in ESLint rule configuration is a continuous process that requires a deep understanding of your project's requirements and the dynamics of your development team. By starting with a sensible baseline configuration, customizing rules to fit your project's needs, gradually increasing strictness, leveraging rule severity levels, collaborating with the team, and regularly evaluating and refining the rules, you can strike an optimal balance that promotes code quality without hindering developer productivity. Remember that finding the sweet spot may require experimentation and adjustments over time as your project evolves. With a well-balanced ESLint rule configuration, you can maintain coding standards, catch potential errors, and foster a productive and collaborative development environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Read more about ESLint
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Mastering ESLint Configurations: Best Practices and Advanced Techniques: &lt;a href="https://devcenter.space/posts/eslint-best-practices/" rel="noopener noreferrer"&gt;link&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Difference between ESLint Plugins and Rules: &lt;a href="https://devcenter.space/posts/eslint-rules-vs-plugins/" rel="noopener noreferrer"&gt;link&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Official documentation: &lt;a href="https://eslint.org/docs/latest/" rel="noopener noreferrer"&gt;link&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://devcenter.space/" rel="noopener noreferrer"&gt;More useful articles&lt;/a&gt;&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>ESLint: Plugins vs Rules (EN)</title>
      <dc:creator>Dmytro</dc:creator>
      <pubDate>Thu, 25 May 2023 19:40:07 +0000</pubDate>
      <link>https://forem.com/dmytrych/eslint-plugins-vs-rules-en-2k8d</link>
      <guid>https://forem.com/dmytrych/eslint-plugins-vs-rules-en-2k8d</guid>
      <description>&lt;p&gt;Article from my personal blog: &lt;a href="https://devcenter.space/" rel="noopener noreferrer"&gt;https://devcenter.space/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ESLint is a powerful tool for checking code quality in JavaScript projects. However, the two main concepts that ESLint users encounter are "rules" and "plugins". Let's find out the differences between them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rules
&lt;/h2&gt;

&lt;p&gt;Rules in ESLint are a set of rules that define the correct or incorrect style of writing code. They help identify potential code problems and stylistic flaws such as missing semicolons, use of undeclared variables, use of forbidden functions, etc. ESLint has a built-in set of rules that you can use by default. However, you can also customize the rules according to your own needs.&lt;/p&gt;

&lt;p&gt;For example, here are some examples of rules:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;semi&lt;/code&gt; - this rule requires the use of a semicolon at the end of each statement.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;no-console&lt;/code&gt; - this rule prohibits the use of the &lt;code&gt;console.log()&lt;/code&gt; function and other &lt;code&gt;console&lt;/code&gt; methods in production code.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Plugins
&lt;/h2&gt;

&lt;p&gt;Plugins in ESlint are additional modules that allow you to extend the functionality of ESlint. They provide additional rules and code inspection capabilities that are not included in the core ruleset. Plugins can be developed by the ESLint community or created by you. To use a plugin, you must first install it via a package manager such as npm or yarn.&lt;/p&gt;

&lt;p&gt;For example, the &lt;code&gt;eslint-plugin-react&lt;/code&gt; plugin is a popular plugin for checking React code.&lt;/p&gt;

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

&lt;p&gt;Rules and plugins are important components of ESlint. Rules help ensure correct code style and identify potential problems, while plugins allow you to extend ESlint's functionality and use specific rules for specific technologies or frameworks. With the right rules setup and use of plugins, you can improve the quality of your code and ensure a more consistent development style.&lt;/p&gt;

&lt;h2&gt;
  
  
  More on this topic
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;How to install ESLint: &lt;a href="https://devcenter.space/posts/eslint-setup" rel="noopener noreferrer"&gt;link&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Official ESLint documentation: &lt;a href="https://eslint.org/docs/latest/" rel="noopener noreferrer"&gt;link&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://devcenter.space/" rel="noopener noreferrer"&gt;More articles&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>node</category>
    </item>
    <item>
      <title>ESLint: Що? Чому? Де? Як?</title>
      <dc:creator>Dmytro</dc:creator>
      <pubDate>Tue, 23 May 2023 17:49:57 +0000</pubDate>
      <link>https://forem.com/dmytrych/eslint-shcho-chomu-die-iak-2c83</link>
      <guid>https://forem.com/dmytrych/eslint-shcho-chomu-die-iak-2c83</guid>
      <description>&lt;p&gt;Стаття з мого блогу: &lt;a href="https://devcenter.space/" rel="noopener noreferrer"&gt;https://devcenter.space/&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Що таке ESLint?
&lt;/h2&gt;

&lt;p&gt;ESLint - це лінтер, для NodeJS застосунків. Його призначення - автоматично виявляти можливі проблеми у вашому коді. Лінтери, і ESLint зокрема, можуть визначати не тільки проблеми у форматуванні коду, а й бачити потенційні баги, проблеми в роботі, пробіли в безпеці вашого застосунку.&lt;/p&gt;

&lt;p&gt;Саме цим ESLint і відрізняється від інструмента для форматування коду, Prettier, який може лише знаходити та фіксити проблеми код-стайлів, але не скаже якщо ваш код містить помилку. Prettier можна використовувати в комбінації з ESLint, для просування код-стайлів. Детальніше про те як встановити Prettier - (&lt;a href="http://devcenter.space/posts/prettier-setup" rel="noopener noreferrer"&gt;в окремій статті&lt;/a&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  Встановлення та конфігурація ESLint
&lt;/h2&gt;

&lt;p&gt;Для того щоб автоматично встановити ESLint та додати усі потрібні для роботи файли, достатньо прописати в терміналі наступну команду:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm init @eslint/config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Після введення команди, вас запитає про те, який функціонал ESLint ви плануєте використовувати. Вибір здійснюється стрілками клавіатури, а саме вікно вибору виглядає так:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3x8n8xmms2aeeypcjep0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3x8n8xmms2aeeypcjep0.png" alt="Вибір пресету ESLint" width="513" height="81"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Відповідно до вашого вибору, будуть підібрані налаштування лінтера.&lt;/p&gt;

&lt;h2&gt;
  
  
  Процес налаштування
&lt;/h2&gt;

&lt;p&gt;Наразі немає сенсу описувати повний процес, проте хочу звернути вашу увагу на кілька пунктів:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;**"How would you like to define a style for your project?"**

В цій опції раджу обрати варіант з `guide`, якщо ви налаштовуєте ESLint вперше. Будь-які потрібні вам налаштування можна буде змінити після встановлення, коли вам це буде потрібно.



**"Which style guide do you want to follow?"**

Знову ж таки, для першого разу раджу встановити `Standard`, і змінити в разі потреби.



**"What format do you want your config file to be in?"**

Тут можете обирати будь-який з форматів. Але наголошу, що більшість статтей в інтернеті використовують саме JSON формат. Ця стаття не буде виключенням.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Після процесу установки, у вашому проекті має з'явитися &lt;code&gt;.eslintrc.*&lt;/code&gt; файл з вибраним розширенням.&lt;/p&gt;

&lt;p&gt;Мій &lt;code&gt;.eslintrc.json&lt;/code&gt; виглядає так:&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Плагіни ESLint
&lt;/h2&gt;

&lt;p&gt;ESLint окрім стандартного набору правил, має інтерфейс для встановлення доповнень(плагінів) у ваш проект. Для того, щоб використати кастомний плагін необхідно встановити його через npm/yarn, після чого додати плагін у список &lt;code&gt;plugins&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Приклад встановлення плагіна Prettier для ESLint можна побачити у &lt;a href="http://devcenter.space/posts/prettier-setup" rel="noopener noreferrer"&gt;минулій статті&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Корисні плагіни для ESLint &lt;a href="https://github.com/dustinspecker/awesome-eslint#plugins" rel="noopener noreferrer"&gt;можна знайти тут&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Інтеграція з IDE
&lt;/h2&gt;

&lt;p&gt;Деякі IDE потребують додаткової конфігурації, щоб увімкнути підсвітку помилок ESLint у редакторі. Плагіни або гайди для налаштування ESLint для популярних IDE:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint" rel="noopener noreferrer"&gt;Visual Studio Code&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.jetbrains.com/help/webstorm/eslint.html#ws_js_eslint_activate" rel="noopener noreferrer"&gt;WebStorm&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://packagecontrol.io/packages/ESLint" rel="noopener noreferrer"&gt;Sublime Text&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://vimawesome.com/plugin/eslint" rel="noopener noreferrer"&gt;Vim&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hackernoon.com/set-up-eslint-in-atom-83dfb3d34fdf" rel="noopener noreferrer"&gt;Atom&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Підсумок
&lt;/h2&gt;

&lt;p&gt;ESLint - лінтер для NodeJS застосунків з обширним функціоналом, який допоможе контролювати дотримання код-стилів у вашому проекті, допоможе у знаходженні потенційних багів, або помилок у синтаксисі. ESLint можна доволі гнучко налаштовувати за допомогою точкового редагування правил його роботи, та встановлення зовнішніх доповнень. ESLint має інтеграцію з обширним списком середовищ розробки.&lt;/p&gt;

&lt;h2&gt;
  
  
  Більше про ESLint
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Різниця між Плагінами та Правилами ESLint: &lt;a href="http://devcenter.space/posts/eslint-rules-vs-plugins" rel="noopener noreferrer"&gt;посилання&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Oфіційна документація: &lt;a href="https://eslint.org/docs/latest/" rel="noopener noreferrer"&gt;посилання&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="http://devcenter.space/" rel="noopener noreferrer"&gt;Більше цікавих статей&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>node</category>
    </item>
  </channel>
</rss>
