<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Alex Ivanovs</title>
    <description>The latest articles on DEV Community by Alex Ivanovs (@stackdiary).</description>
    <link>https://dev.to/stackdiary</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%2F801184%2Fe7509904-3983-4863-b5ca-528f89a85a08.jpg</url>
      <title>DEV Community: Alex Ivanovs</title>
      <link>https://dev.to/stackdiary</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/stackdiary"/>
    <language>en</language>
    <item>
      <title>async/await</title>
      <dc:creator>Alex Ivanovs</dc:creator>
      <pubDate>Thu, 16 Mar 2023 06:19:35 +0000</pubDate>
      <link>https://dev.to/stackdiary/asyncawait-35im</link>
      <guid>https://dev.to/stackdiary/asyncawait-35im</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Async/await simplifies asynchronous programming by allowing developers to write code that looks and behaves like synchronous code, improving readability and understandability.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This page is a follow-up branch of the in-depth article "&lt;a href="https://stackdiary.com/guides/async-in-js/"&gt;Async in JS: How does it work&lt;/a&gt;", if you'd like to learn about the history of asynchronous JavaScript and its evolution, refer to it.&lt;/p&gt;

&lt;h2&gt;
  
  
  In a nutshell
&lt;/h2&gt;

&lt;p&gt;When you use the &lt;code&gt;async&lt;/code&gt; keyword before a function definition, it indicates that the function will be asynchronous. This means that the function is designed to work with asynchronous operations, such as network requests or reading files, without blocking the main execution thread. In JavaScript, asynchronous functions are usually implemented using promises.&lt;/p&gt;

&lt;p&gt;As a result, when you declare a function as &lt;code&gt;async&lt;/code&gt;, the return value of that function is automatically wrapped in a Promise. Even if the return value is not a promise itself, JavaScript will create a promise that resolves to that value.&lt;/p&gt;

&lt;p&gt;Here's an 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="c1"&gt;// An asynchronous function&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getUserName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Simulate an asynchronous operation (e.g., fetching data from a server)&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;simulatedData&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="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Alice&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Bob&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Charlie&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;simulatedData&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Usage&lt;/span&gt;
&lt;span class="nx"&gt;getUserName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`User 1: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Output: User 1: Alice&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, the &lt;code&gt;getUserName&lt;/code&gt; function is declared as &lt;code&gt;async&lt;/code&gt;. Even though it returns a simple value from the &lt;code&gt;simulatedData&lt;/code&gt; object, the return value is automatically wrapped in a promise. When we call the &lt;code&gt;getUserName&lt;/code&gt; function, we can use the &lt;code&gt;then&lt;/code&gt; method to handle the resolved value, just like we would with any other promise.&lt;/p&gt;




&lt;p&gt;Asynchronous functions are essential when dealing with operations that take an unpredictable amount of time to complete, such as making API calls, interacting with databases, or reading files. These operations are not executed immediately; instead, the code sends a request and waits for the response.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;await&lt;/code&gt; keyword is used inside an &lt;code&gt;async&lt;/code&gt; function to pause the execution of the function until the asynchronous operation is completed. It allows you to write code that appears synchronous, even though it's performing asynchronous tasks. This makes the code more readable and easier to understand.&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;// Import the 'fs' module to work with the file system&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;promises&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// An async function to read a file&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;readFileContent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;filePath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Use the 'await' keyword to wait for the file to be read&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;content&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;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;readFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;filePath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;utf-8&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`File content: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Error reading the file: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Usage&lt;/span&gt;
&lt;span class="nx"&gt;readFileContent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./example.txt&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;In this example, we're using the &lt;code&gt;fs.promises&lt;/code&gt; module to read a file. The &lt;code&gt;readFile&lt;/code&gt; function is asynchronous, so it returns a promise. Inside the &lt;code&gt;readFileContent&lt;/code&gt; async function, we use the &lt;code&gt;await&lt;/code&gt; keyword to wait for the &lt;code&gt;fs.readFile&lt;/code&gt; promise to resolve. Once the promise resolves, the file's content is logged to the console. If there's an error reading the file, the catch block logs the error message.&lt;/p&gt;

&lt;h2&gt;
  
  
  Call chains vs async/await
&lt;/h2&gt;

&lt;p&gt;The async/await keywords in JavaScript don't introduce new functionality; they simply make it easier to work with promises. They allow you to write cleaner and more intuitive code compared to using chained &lt;code&gt;then&lt;/code&gt; and &lt;code&gt;catch&lt;/code&gt; callbacks.&lt;/p&gt;

&lt;p&gt;Here's an example illustrating the difference between using promises with a call chain and using async/await.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Using a call chain with promises:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;fetchData&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="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Data fetched&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="mi"&gt;1000&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="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;processData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; and processed`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;1000&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="c1"&gt;// Chained promises with then and catch&lt;/span&gt;
&lt;span class="nx"&gt;fetchData&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;processData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Output: Data fetched and processed&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Error: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Using async/await:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;fetchDataAndProcess&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&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;data&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;fetchData&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;result&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;processData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Output: Data fetched and processed&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Error: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Call the async function&lt;/span&gt;
&lt;span class="nx"&gt;fetchDataAndProcess&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In both examples, we fetch and process data using promises. The first example uses a call chain with &lt;code&gt;then&lt;/code&gt; and &lt;code&gt;catch&lt;/code&gt;, while the second example uses the async/await keywords. The async/await version is easier to understand because it looks more like synchronous code. It's also more straightforward to handle errors using try/catch blocks, making it a popular choice for developers working with asynchronous operations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tips &amp;amp; best practices
&lt;/h2&gt;

&lt;p&gt;Below you'll find some personal tips but also industry best practices when working with async/await.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Always use async/await instead of then() chains and callbacks.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Async/await is easier to read, debug, and manage compared to chaining multiple &lt;code&gt;then()&lt;/code&gt; and &lt;code&gt;catch()&lt;/code&gt; functions or using callback functions.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;Await &lt;strong&gt;should not&lt;/strong&gt; be used outside of asynchronous functions.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;await&lt;/code&gt; keyword can only be used inside an async function. If you want to perform an asynchronous operation in the global scope, you must use &lt;code&gt;then()&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;Use &lt;code&gt;await Promise.all([...])&lt;/code&gt; to execute several independent asynchronous functions in parallel.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Instead of waiting for one asynchronous function to complete before executing the next, you can run multiple independent async functions concurrently using &lt;code&gt;Promise.all()&lt;/code&gt;. This can help improve the overall performance of your code.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&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="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Returns the information about the user&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getNews&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Returns the list of news&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Using Promise.all to run getUser() and getNews() concurrently&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;news&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;all&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nx"&gt;getNews&lt;/span&gt;&lt;span class="p"&gt;()]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Don't mix async/await and Promise.then syntax.

&lt;ul&gt;
&lt;li&gt;To maintain consistency and readability in your code, try to stick to one approach throughout your project: either async/await or Promise.then. Mixing the two can make your code harder to read and maintain.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Use try/catch blocks for error handling.

&lt;ul&gt;
&lt;li&gt;When using async/await, it's a good practice to handle errors with try/catch blocks. This approach is more consistent and easier to understand compared to handling errors with Promise.catch().&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&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="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;fetchData&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;try&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;data&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;fetchSomeData&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Data fetched:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Error fetching data:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Avoid "async/await hell."

&lt;ul&gt;
&lt;li&gt;Similar to "callback hell," "async/await hell" refers to a situation where you have multiple nested async functions, making the code hard to read and maintain. Instead, try to break down your code into smaller, reusable async functions.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Keep your asynchronous functions focused.

&lt;ul&gt;
&lt;li&gt;Try to create asynchronous functions that perform a single, well-defined task. This approach makes your code easier to understand, test, and maintain.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;Promise.race([...])&lt;/code&gt; when you need the result of the fastest promise.

&lt;ul&gt;
&lt;li&gt;If you have several asynchronous operations and need to get the result of the one that completes first, use &lt;code&gt;Promise.race()&lt;/code&gt;. It returns a promise that resolves or rejects as soon as one of the input promises settles.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&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="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;fetchFromAPI_A&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Fetch data from API A&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;fetchFromAPI_B&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Fetch data from API B&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Using Promise.race to get the result from the fastest API&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fastestResult&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;race&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;fetchFromAPI_A&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nx"&gt;fetchFromAPI_B&lt;/span&gt;&lt;span class="p"&gt;()]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By adhering to these recommendations, you can improve the readability, maintainability, and performance of your JavaScript code when working with asynchronous operations using async/await and promises.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>CSS :has() Parent Selector</title>
      <dc:creator>Alex Ivanovs</dc:creator>
      <pubDate>Wed, 19 Oct 2022 15:01:59 +0000</pubDate>
      <link>https://dev.to/stackdiary/css-has-parent-selector-2389</link>
      <guid>https://dev.to/stackdiary/css-has-parent-selector-2389</guid>
      <description>&lt;p&gt;The &lt;code&gt;:has()&lt;/code&gt; relational pseudo-class is officially recognized as a &lt;strong&gt;Parent Selector&lt;/strong&gt;, and in the actual spec [&lt;a href="https://www.w3.org/TR/selectors-4/#relational"&gt;Selectors Level 4&lt;/a&gt;], it is described as a relative selector that accepts “&lt;a href="https://www.w3.org/TR/selectors-4/#typedef-forgiving-relative-selector-list"&gt;forgiving-relative-selector-list&lt;/a&gt;“. However, &lt;code&gt;:has()&lt;/code&gt; is extremely capable as far as selectors go, and there’s plenty of proof that it is &lt;a href="https://www.bram.us/2021/12/21/the-css-has-selector-is-way-more-than-a-parent-selector/#more-than"&gt;more than&lt;/a&gt; just a &lt;em&gt;parent selector&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Syntax&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The syntax of the &lt;code&gt;:has()&lt;/code&gt; pseudo-class is relatively simple and easy to learn to get started, because its semantics are very clear and consistent with the rendering presentation, meaning that the so-and-so element will match if it matches the so-and-so selector.&lt;/p&gt;

&lt;p&gt;As a simple example, the following function means that if the element has an &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; element inside the &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; element, the &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; element will match.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;a:has(img) { 
  display: block; 
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;We can use this selector to easily distinguish whether it is a text link or an image link and set different CSS styles.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;:has()&lt;/code&gt; pseudo-class supports all CSS selectors. E.g.:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;a:has(&amp;gt; img) { 
display: block; 
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The above function indicates that &lt;code&gt;a&lt;/code&gt; elements whose matching child element is an &lt;code&gt;img&lt;/code&gt; element will be matched, while more distantly related descendant elements will not be considered.&lt;/p&gt;

&lt;p&gt;Note that in the above code, the &lt;code&gt;:has&lt;/code&gt; pseudo-class argument - &lt;code&gt;&amp;gt;&lt;/code&gt; selector - is written directly at the top of the argument, rather than &lt;code&gt;a:has(a &amp;gt; img)&lt;/code&gt;. The &lt;code&gt;:has()&lt;/code&gt; pseudo-class has an invisible &lt;code&gt;:scope&lt;/code&gt; pseudo-class at the top of its argument, so it is prohibited to write &lt;code&gt;a:has(a &amp;gt; img)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Similarly, you can use selectors like &lt;code&gt;+&lt;/code&gt; or &lt;code&gt;~&lt;/code&gt; to achieve the effect of a "front sibling selector", where the front element is selected based on the back sibling element. Like so:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;h3:has(+ p) { 
font-size: 1.5rem; 
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The above query indicates a match for an &lt;code&gt;h3&lt;/code&gt; element followed by an &lt;code&gt;p&lt;/code&gt; element. The &lt;code&gt;:has()&lt;/code&gt; pseudo-class also supports complex selectors and selector lists. E.g.:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;article:has(h3, p) { 
   background-color: #f3f3f3;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The above query indicates that only &lt;code&gt;h3&lt;/code&gt; elements or &lt;code&gt;p&lt;/code&gt; elements inside the article elements will match: as an &lt;strong&gt;or&lt;/strong&gt; relationship, not a &lt;strong&gt;with&lt;/strong&gt; relationship.&lt;/p&gt;

&lt;p&gt;If you want the relationship to be &lt;strong&gt;with&lt;/strong&gt;, i.e., both &lt;code&gt;h3&lt;/code&gt; elements and &lt;code&gt;p&lt;/code&gt; elements to match, you can write it like so:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;article:has(h3):has(p) { 
   background-color: #f3f3f3; 
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;:has()&lt;/code&gt; pseudo-class can also be mixed with other pseudo-classes, such as &lt;code&gt;:checked&lt;/code&gt;, &lt;code&gt;:enabled&lt;/code&gt;, etc., or even with other logical pseudo-classes, such as &lt;code&gt;:not&lt;/code&gt;. E.g.:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;section:not(:has(h3)) {
  border: 1px solid yellow;
}

section:has(:not(h3)) {
  color: orange;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Note that the two queries above have different meanings.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The former selector means that &lt;code&gt;section&lt;/code&gt; elements that do not contain &lt;code&gt;h3&lt;/code&gt; elements have a yellow border, while the latter means that &lt;code&gt;section&lt;/code&gt; elements that contain elements that are not &lt;code&gt;h3&lt;/code&gt; elements are orange in color.&lt;/p&gt;

&lt;p&gt;It is honestly confusing for &lt;em&gt;everyone&lt;/em&gt;. But once you understand that &lt;strong&gt;not -&amp;gt; has&lt;/strong&gt; means &lt;em&gt;has not&lt;/em&gt;, it gets easier.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Examples&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;:has()&lt;/code&gt; pseudo-class has been available for quite some time now (either under browser flags or with a polyfill), and the possibilities of what this parent selector will be able to do will have to be unraveled over time.&lt;/p&gt;

&lt;p&gt;In the meantime, this section covers examples of creative ways in which &lt;code&gt;:has()&lt;/code&gt; is already being utilized.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;#1: Styling&lt;/strong&gt; &lt;code&gt;figcaption&lt;/code&gt; &lt;strong&gt;only if it is present&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt; &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0Kal5Xr---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n7t1pla037nzcl6sueoa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0Kal5Xr---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n7t1pla037nzcl6sueoa.png" alt="Image description" width="880" height="225"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;See the Pen &lt;a href="https://codepen.io/jensimmons/pen/eYGKNYy"&gt;:has() Demo #1 — Figure variations&lt;/a&gt; by Jen Simmons (&lt;a href="https://codepen.io/jensimmons"&gt;@jensimmons&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;#2: Carousel gallery with scale and gap effect in pure CSS&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt; &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vFfI1Mah--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2ugpjb745f4sxnwm264s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vFfI1Mah--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2ugpjb745f4sxnwm264s.png" alt="Image description" width="796" height="532"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;See the Pen &lt;a href="https://codepen.io/kevinpowell/pen/PoeGYGK"&gt;:has() example four&lt;/a&gt; by Kevin (&lt;a href="https://codepen.io/kevinpowell"&gt;@kevinpowell&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;#3: Creating a native color theme switcher&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt; &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--h7DfvMVG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/teysnk6v9w472a61j3g6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--h7DfvMVG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/teysnk6v9w472a61j3g6.png" alt="Image description" width="803" height="342"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;See the Pen &lt;a href="https://codepen.io/shadeed/pen/OJzoxgo"&gt;CSS :has - Color theme&lt;/a&gt; by Ahmad Shadeed (&lt;a href="https://codepen.io/shadeed"&gt;@shadeed&lt;/a&gt;)&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Browser Support&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7X5VPtE8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://caniuse.bitsofco.de/image/css-has.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7X5VPtE8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://caniuse.bitsofco.de/image/css-has.jpg" alt="Data on support for the css-has feature across the major browsers from caniuse.com" width="800" height="388"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>css</category>
      <category>webdev</category>
      <category>design</category>
    </item>
    <item>
      <title>Stable Diffusion: Tutorials, Resources, and Tools</title>
      <dc:creator>Alex Ivanovs</dc:creator>
      <pubDate>Sat, 10 Sep 2022 06:17:40 +0000</pubDate>
      <link>https://dev.to/stackdiary/stable-diffusion-tutorials-resources-and-tools-83i</link>
      <guid>https://dev.to/stackdiary/stable-diffusion-tutorials-resources-and-tools-83i</guid>
      <description>&lt;p&gt;On the 22nd of August, &lt;a href="https://stability.ai/blog/stable-diffusion-public-release"&gt;Stability.ai founder Emad Mostaque announced the release of Stable Diffusion&lt;/a&gt; - an AI generative art model that has not only superior capabilities to the likes of DALL·E 2 but is also available as an open-source project. In those 2 weeks since its release, people have abandoned their personal endeavors and projects to give Stable Diffusion their full attention.&lt;/p&gt;

&lt;p&gt;I was already quite excited &lt;a href="https://openai.com/dall-e-2/"&gt;when OpenAI announced DALL·E 2&lt;/a&gt;, and I was also fortunate enough to get early access. But having toyed around with Stable Diffusion for the last couple of days, I can say that DALL·E 2 doesn't come even close to what Stable Diffusion brings to the table.&lt;/p&gt;

&lt;p&gt;And the fact that it is open-source also makes it much more accessible. In just 2 weeks, sites like &lt;a href="https://lexica.art/"&gt;Lexica&lt;/a&gt; have archived over 10 million AI-generated images. I also fully expect that developers will make steady strides to integrate Stable Diffusion with the most popular graphic design tools, such as Figma, Sketch, and others. The ability to generate high-quality art on the go is unprecedented.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AkCkBpVL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://stackdiary.com/wp-content/uploads/2022/09/ddf10c66-5f2b-4c29-8531-eb02cf4d848a.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AkCkBpVL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://stackdiary.com/wp-content/uploads/2022/09/ddf10c66-5f2b-4c29-8531-eb02cf4d848a.webp" alt="kerala village, sharp focus, wide shot, trending on ArtStation, masterpiece, by Greg Rutkowski, by Ross Tran, by Fenghua Zhong, octane, soft render, oil on canvas, colorful, cinematic, environmental concept art" width="880" height="629"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;"Kerala village, sharp focus, wide shot, trending on artstation, masterpiece, by greg rutkowski, by ross tran, by fenghua zhong, octane, soft render, oil on canvas, colorful, cinematic, environmental concept art"&lt;/p&gt;

&lt;p&gt;The purpose of this article is to list all the interesting and relevant tutorials, resources, and tools to help you get up to speed with Stable Diffusion quickly. I do believe over the coming months we're going to see a massive influx of projects that specialize in extracting the most potential out of Stable Diffusion, and I will do my best to keep this article updated accordingly.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  👉 &lt;strong&gt;Tutorials&lt;/strong&gt; - this section is focused heavily on topics such as &lt;em&gt;"How to use Stable Diffusion?"&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;  💻 &lt;strong&gt;Resources&lt;/strong&gt; - this section is focused on queries such as &lt;em&gt;"What is Stable Diffusion?"&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;  🚀 &lt;strong&gt;Tools&lt;/strong&gt; - this section is based on tools that let you use Stable Diffusion yourself.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So without further ado - let's start with the basics.&lt;/p&gt;




&lt;h2&gt;
  
  
  Resources &amp;amp; Information
&lt;/h2&gt;

&lt;p&gt;One of the first questions a lot of people have about Stable Diffusion is the license that this model is published under, and whether the generated art is &lt;em&gt;free&lt;/em&gt; to use for personal and commercial projects.&lt;/p&gt;

&lt;p&gt;The license Stable Diffusion is using is &lt;strong&gt;CreativeML Open RAIL-M&lt;/strong&gt;, and can be &lt;a href="https://huggingface.co/spaces/CompVis/stable-diffusion-license"&gt;read in full over at Hugging Face&lt;/a&gt;. In short, &lt;em&gt;"Open Responsible AI Licenses (Open RAIL) are licenses designed to permit free and open access, re-use, and downstream distribution of derivatives of AI artifacts as long as the behavioral-use restrictions always apply (including to derivative works)."&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;A more detailed explanation for this license is available on &lt;a href="https://bigscience.huggingface.co/blog/bigscience-openrail-m"&gt;this BigScience page&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  What images were used to train the Stable Diffusion model?
&lt;/h3&gt;

&lt;p&gt;AI modeling is the means of creating and training Machine Learning algorithms for a specific purpose. In this case, the purpose of generating images from user prompts.&lt;/p&gt;

&lt;p&gt;If you're curious as to which images Stable Diffusion used - &lt;a href="https://waxy.org/2022/08/exploring-12-million-of-the-images-used-to-train-stable-diffusions-image-generator/"&gt;Andy Baio together with Simon Willison did a thorough analysis&lt;/a&gt; of over 12 million images (from a total of 2.3 billion) that were used to train the Stable Diffusion model.&lt;/p&gt;

&lt;p&gt;Here are some of the key takeaways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  The datasets which were used to train Stable Diffusion were the ones put together by &lt;a href="https://laion.ai/"&gt;LAION&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;  Out of the 12 million images they sampled, 47% of the entire sample size came from 100 domains, with Pinterest yielding as much as 8.5% of the entire dataset. Other top sources included WordPress.com, Blogspot, Flickr, DeviantArt, and Wikimedia.&lt;/li&gt;
&lt;li&gt;  Stable Diffusion doesn't restrict the use of generating art from people's names (be it celebrities or otherwise).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It will be interesting to see how the model evolves, and whether companies will be willing to contribute their own media to help Stable Diffusion grow.&lt;/p&gt;

&lt;h3&gt;
  
  
  Where to find Stable Diffusion examples &amp;amp; prompts?
&lt;/h3&gt;

&lt;p&gt;One of the ways in which Stable Diffusion differs from the likes of DALL·E is that to get the most out of Stable Diffusion you have to learn about its &lt;strong&gt;modifiers&lt;/strong&gt;. One modifier, in particular, is called the &lt;strong&gt;seed&lt;/strong&gt; - whenever you generate an image with Stable Diffusion, that image will be assigned a seed, which can also be understood as the general composition of that image. So, if you enjoyed a particular image and wish to replicate its style (or at least as close as possible to it) - you can use seeds.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BMser1Tt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://stackdiary.com/wp-content/uploads/2022/09/Lexica-1024x500.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BMser1Tt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://stackdiary.com/wp-content/uploads/2022/09/Lexica-1024x500.png" alt="Lexica" width="880" height="430"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The best platform for finding example images and the prompts that were used to generate those images is &lt;a href="https://lexica.art/"&gt;Lexica&lt;/a&gt;, which archives over 10 million sample artworks. Each artwork includes its full prompt, but also the seed number which you can then reuse yourself.&lt;/p&gt;




&lt;h2&gt;
  
  
  Tools &amp;amp; Software
&lt;/h2&gt;

&lt;p&gt;If you've seen or been captivated by the art created with Stable Diffusion, you might be wondering whether you can try it out for yourself. And the answer is yes, there are multiple ways to try Stable Diffusion for free, including doing so from the browser or your own machine.&lt;/p&gt;

&lt;p&gt;The official way to do so is to use &lt;a href="https://beta.dreamstudio.ai/"&gt;the DreamStudio platform&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZM3wGVmm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://stackdiary.com/wp-content/uploads/2022/09/DreamStudio-example.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZM3wGVmm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://stackdiary.com/wp-content/uploads/2022/09/DreamStudio-example.png" alt="DreamStudio example" width="880" height="426"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Anyone can register for free, and new accounts get a complimentary 200 free tokens. These tokens are sufficient for 200 generations as long as you don't increase complexity and don't change the height and width past the 512x512 default setting. But if you do increase the complexity, you're probably going to run out of your tokens rather quickly.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to run Stable Diffusion on your own machine?
&lt;/h3&gt;

&lt;p&gt;At this time, the most popular solution for running Stable Diffusion locally is &lt;a href="https://github.com/sd-webui/stable-diffusion-webui"&gt;the Stable Diffusion Web UI repo available on GitHub&lt;/a&gt;. Based on the Gradio GUI - this is as close as it gets to the actual DreamStudio interface, and you can wave goodbye to any kind of limitations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What are the PC requirements for Stable Diffusion?&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;-&lt;/strong&gt; 4GB (more is preferred) VRAM GPU (Official support for Nvidia only!)&lt;br&gt;&lt;br&gt;
&lt;strong&gt;-&lt;/strong&gt; AMD users &lt;a href="https://www.reddit.com/r/StableDiffusion/comments/ww436j/howto_stable_diffusion_on_an_amd_gpu/"&gt;check here&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;-&lt;/strong&gt; M1/M2 users &lt;a href="https://www.reddit.com/r/StableDiffusion/comments/wx0tkn/stablediffusion_runs_on_m1_chips/"&gt;check here&lt;/a&gt; and &lt;a href="https://twitter.com/levelsio/status/1565731907664478209"&gt;here also&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Keep in mind that to use the Web UI repo, you will need to download the model yourself from Hugging Face. Make sure you fully read &lt;a href="https://github.com/sd-webui/stable-diffusion-webui/wiki/Installation"&gt;the Installation guide&lt;/a&gt; (Windows) to set it up properly. For Linux, &lt;a href="https://github.com/sd-webui/stable-diffusion-webui/wiki/Linux-Automated-Setup-Guide"&gt;check this guide&lt;/a&gt;. And you can also get it up and running on Google Colab - &lt;a href="https://github.com/altryne/sd-webui-colab"&gt;guide here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  How big is the Stable Diffusion model?
&lt;/h3&gt;

&lt;p&gt;As I mention above, you have to download the Stable Diffusion model yourself, and the link to do so can be found &lt;a href="https://huggingface.co/CompVis/stable-diffusion-v-1-4-original/tree/main"&gt;here&lt;/a&gt;. You will need to create an account on Hugging Face, and afterward, accept the license terms for the model before you're able to view and download its files.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uFVHiRtj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://stackdiary.com/wp-content/uploads/2022/09/stable-diffusion-model-files-on-hugging-face.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uFVHiRtj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://stackdiary.com/wp-content/uploads/2022/09/stable-diffusion-model-files-on-hugging-face.png" alt="stable diffusion model files on hugging face" width="880" height="287"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One of the questions people have is, &lt;em&gt;"How come the model is only 4GB in size even though it has been made from over 2 billion images?"&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;And the best answer to this question comes from &lt;a href="https://news.ycombinator.com/item?id=32785768"&gt;a Hacker News user juliendorra&lt;/a&gt; ⟶&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;That’s the interesting part: all the images generated are derived from a less than 4gb model (the trained weights of the neural network).&lt;br&gt;
So in a way, hundreds of billions of possible images are all stored in the model (each a vector in multidimensional latent space) and turned into pixels on demand (drived by the language model that knows how to turn words into a vector in this space)&lt;br&gt;
As it’s deterministic (given the exact same request parameters, random seed included, you get the exact same image) it’s a form of compression (or at least encoding decoding) too: I could send you the parameters for 1 million images that you would be able to recreate on your side, just as a relatively small text file.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Tutorials &amp;amp; Guides
&lt;/h2&gt;

&lt;p&gt;The following section is dedicated entirely to tutorials and guides to help you extract the most juice out of your Stable Diffusion prompts. As I said, I will do my best to keep this updated as more guides become available and a better understanding of the model is gained.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ultimate Beginner's Guide
&lt;/h3&gt;

&lt;p&gt;Arman Chaudhry published &lt;a href="https://docs.google.com/document/d/1sgXAnFMEfx-I_Harts7cEGEPAtmWGvl62yJHByPE0ZI/edit"&gt;a compact Google Docs presentation&lt;/a&gt; on the essentials of SD.&lt;/p&gt;

&lt;p&gt;This guide covers all of the modifiers that SD supports but also recommends the best practices for width/height settings, as well as common mistakes to avoid.&lt;/p&gt;

&lt;h3&gt;
  
  
  Stable Diffusion Akashic Records
&lt;/h3&gt;

&lt;p&gt;If you're looking to do a deep dive (or need references for research) - the &lt;a href="https://github.com/Maks-s/sd-akashic"&gt;SD Akashic Records&lt;/a&gt; repository has an astounding amount of resources for you to study.&lt;/p&gt;

&lt;p&gt;You'll find everything from keyword usage, to prompt optimization, to style guides. There are also mentions of several tools, outside of those already mentioned in this article.&lt;/p&gt;

&lt;h3&gt;
  
  
  Stable Diffusion Prompt Cheatsheet
&lt;/h3&gt;

&lt;p&gt;If you're looking for inspiration to apply custom styles and effects to your prompts, &lt;a href="https://moritz.pm/posts/parameters"&gt;check out this blog post from Moritz&lt;/a&gt;. It covers prompt additions for concepts like 2D &amp;amp; 3D art, details, lighting, colors, and environments.&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>machinelearning</category>
      <category>stablediffusion</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Tailwind CSS: Cheat Sheet (Chrome Extension)</title>
      <dc:creator>Alex Ivanovs</dc:creator>
      <pubDate>Thu, 30 Jun 2022 07:08:31 +0000</pubDate>
      <link>https://dev.to/stackdiary/tailwind-css-cheat-sheet-chrome-extension-4347</link>
      <guid>https://dev.to/stackdiary/tailwind-css-cheat-sheet-chrome-extension-4347</guid>
      <description>&lt;p&gt;Are you new to Tailwind CSS or maybe you’re returning to give it a second try? In any case, having quick access to the Tailwind CSS cheat sheet is a fundamental part of working with the framework. Everyone knows Tailwind CSS has a peculiar syntax.&lt;/p&gt;

&lt;p&gt;The two most popular cheat sheets are either &lt;a href="https://tailwindcss.com/docs/installation"&gt;the official documentation&lt;/a&gt; from Tailwind Labs or the &lt;a href="https://tailwindcomponents.com/cheatsheet/"&gt;custom-built reference&lt;/a&gt; by Tailwind Components. And now, thanks to &lt;a href="https://github.com/shahidshaikhs"&gt;Shahid Shaikh&lt;/a&gt;, you can also get the Tailwind CSS cheat sheet as a Chrome extension.&lt;/p&gt;

&lt;p&gt;You can get it directly from the &lt;a href="https://chrome.google.com/webstore/detail/tailwind-cheat-sheet-exte/jmggagicdeomaenmjjlphbamdaeojcol"&gt;Google Web Store&lt;/a&gt; or visit the &lt;a href="https://github.com/shahidshaikhs/Tailwind-Cheat-Sheet-Chrome-Extension"&gt;GitHub&lt;/a&gt; project page.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;All the references are taken from the Tailwind Components page.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Once you install the extension, you can click on the icon in your extension bar and have quick access to various classes and their associated properties. For each property, there’s also a link to the official docs page in case you need additional details. There is a search feature also.&lt;/p&gt;

&lt;p&gt;So, for example, if you need a quick reference to all the available &lt;code&gt;place-items&lt;/code&gt; properties, you can just search for that and click to copy to the clipboard.&lt;/p&gt;

&lt;p&gt;The project is open-source, so feel free to contribute. I think the search feature could use a little bit of fine-tuning, as I found quite a few overlaps when searching for classes. And, it would probably be nice if someone could port this over for Mozilla users, too.&lt;/p&gt;

</description>
      <category>tailwindcss</category>
      <category>css</category>
      <category>chrome</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How to Add a Mega Menu on a WordPress Site</title>
      <dc:creator>Alex Ivanovs</dc:creator>
      <pubDate>Wed, 23 Mar 2022 18:49:25 +0000</pubDate>
      <link>https://dev.to/stackdiary/how-to-add-a-mega-menu-on-a-wordpress-site-7bm</link>
      <guid>https://dev.to/stackdiary/how-to-add-a-mega-menu-on-a-wordpress-site-7bm</guid>
      <description>&lt;p&gt;In this article, we are going to discuss the topic of mega menus, and how to add a mega menu to a WordPress site. We will explore what a mega menu is, why is it beneficial, and what is the best WordPress plugin for adding a mega menu to your blog.&lt;/p&gt;

&lt;p&gt;Website navigation or a menu for short is one of the quintessential design elements.&lt;/p&gt;

&lt;p&gt;It is impossible to have &lt;a href="https://alistapart.com/article/horizdropdowns/"&gt;a good page layout without navigation&lt;/a&gt;. And in the case of mega menus, it is a flexible solution to display a contextual hierarchy of your site's content.&lt;/p&gt;

&lt;p&gt;For starters, a mega menu can help display the larger context of what your website is about.&lt;/p&gt;

&lt;p&gt;But, also:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Show your most popular content categories.&lt;/li&gt;
&lt;li&gt;  Display trending articles or blog posts.&lt;/li&gt;
&lt;li&gt;  Include information about your brand, such as social links, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here is an example taken from the &lt;em&gt;IEEE Spectrum&lt;/em&gt; magazine:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ewt0N3CI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mxlx5x05lfprwi0wh2gs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ewt0N3CI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mxlx5x05lfprwi0wh2gs.png" alt="IEEE Spectrum" width="880" height="444"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This one big navigation menu is able to convey practically everything about the sites' structure. And, one could say that it is also pleasing to the eye. Browsing large contextual navigation through a drop-down menu is quite impractical. Whereas a mega menu efficiently gives the reader quick access to your most important content.&lt;/p&gt;

&lt;p&gt;Other notable brands who use mega menus include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Amazon, the largest eCommerce platform in the world.&lt;/li&gt;
&lt;li&gt;  Asana, one of the leading project management tools.&lt;/li&gt;
&lt;li&gt;  Adobe, the leading software company specializing in design.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And many, many more!&lt;/p&gt;

&lt;h2&gt;
  
  
  Is a mega menu SEO friendly?
&lt;/h2&gt;

&lt;p&gt;One of the first questions people ask about mega menus is whether they are search engine friendly. And the answer is yes. Internal links are &lt;a href="https://developers.google.com/search/blog/2008/10/importance-of-link-architecture"&gt;extremely important for SEO&lt;/a&gt;, and using a large menu you can add dozens of links to your pages without hindering the user experience.&lt;/p&gt;

&lt;p&gt;It's also well-known that &lt;a href="https://developers.google.com/search/docs/advanced/javascript/javascript-seo-basics"&gt;Google Crawler can interpret JavaScript&lt;/a&gt;, which makes it a non-issue for indexing-related concerns.&lt;/p&gt;

&lt;p&gt;If you look at more popular platforms like Shopify, WooCommerce, and others. All of them implement some kind of a mega menu structure for displaying product information.&lt;/p&gt;

&lt;h2&gt;
  
  
  Can you add a mega menu without a plugin?
&lt;/h2&gt;

&lt;p&gt;It is possible, yes. But, in a lot of ways - impractical. There are plenty of &lt;a href="https://github.com/lokomotivan/mega-menu"&gt;open-source libraries on GitHub&lt;/a&gt; that showcase mega-menu functionality with JavaScript.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--I8CyHb1b--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vo9sj3cihkejh2cyjmx4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--I8CyHb1b--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vo9sj3cihkejh2cyjmx4.png" alt="add a mega menu without a plugin" width="880" height="328"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But, in terms of adding this to WordPress - it's way too much work. Needless to say, you might have to add items individually. It is much easier to do this through a plugin.&lt;/p&gt;

&lt;p&gt;And this is also going to be the next topic of discussion.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is the best plugin for adding a mega menu?
&lt;/h2&gt;

&lt;p&gt;On the WordPress plugin repository, there are hundreds of plugins that provide this functionality. However, calling something the best is often a matter of subjective opinion.&lt;/p&gt;

&lt;p&gt;In some cases, plugins are locked behind page builders like Elementor and Visual Composer. And, other times - the plugin provides very minimal functionality without pro features.&lt;/p&gt;

&lt;p&gt;So, for this guide - we are going to be focusing on the &lt;a href="https://wordpress.org/plugins/easymega/"&gt;EasyMega&lt;/a&gt; plugin. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1sEyeuRR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1d40k8plb10jvj1j3i0p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1sEyeuRR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1d40k8plb10jvj1j3i0p.png" alt="EasyMega plugin" width="880" height="272"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;_It is completely free to download and use.&lt;/p&gt;

&lt;p&gt;Let's take a look at the core features for EasyMega:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Native integration with the Customizer design system for WordPress.&lt;/li&gt;
&lt;li&gt;  Preview changes in real-time.&lt;/li&gt;
&lt;li&gt;  Use &lt;em&gt;Drag &amp;amp; Drop&lt;/em&gt; to create the perfect mega menu layout.&lt;/li&gt;
&lt;li&gt;  Choose between Full-Width or Boxed.&lt;/li&gt;
&lt;li&gt;  Change the alignment of how menu items appear to the reader.&lt;/li&gt;
&lt;li&gt;  ...and a lot more!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And it's extremely simple to use. Don't believe me? Let's see how easy it is to add a mega menu to your site with a simple tutorial.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to add a mega menu using the EasyMega plugin
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--npaHjhTs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ousy6tlc5217c2de3ckr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--npaHjhTs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ousy6tlc5217c2de3ckr.png" alt="add a mega menu using the EasyMega plugin" width="880" height="350"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First and foremost, you want to grab the plugin by going to &lt;strong&gt;Plugins -&amp;gt; Add New&lt;/strong&gt; from your WordPress dashboard. On this page, simply search for EasyMega and Install the plugin.&lt;/p&gt;

&lt;p&gt;Once you are done you will be taken to the plugin introduction page. You can skip this entirely and go to your homepage to open &lt;em&gt;&lt;strong&gt;Customizer&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;From Customizer, you want to navigate to Menus and select your Primary Navigation. &lt;/p&gt;

&lt;p&gt;Like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XE_55U3K--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gv8ue37cus7x0zvea7bf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XE_55U3K--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gv8ue37cus7x0zvea7bf.png" alt="select your Primary Navigation" width="723" height="817"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Under the Mega Menu Settings, simply click "Activate mega menu features" and save your changes. At this stage, you can click on any of your existing Menu items and select the Mega Menu features. &lt;/p&gt;

&lt;p&gt;Like so:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--e4uSxGjw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ikofi0yqikov3axkq8oq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--e4uSxGjw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ikofi0yqikov3axkq8oq.png" alt="Mega Menu features" width="880" height="426"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By doing this, a new panel will appear at the bottom of the page where you can start doing customizations.&lt;/p&gt;

&lt;p&gt;You can also click on the &lt;em&gt;Live Preview&lt;/em&gt; button to see changes in real-time. This will help you avoid having to go back and forth between changes.&lt;/p&gt;

&lt;p&gt;The next step is to start adding items to your menu. For this tutorial, we are using the &lt;em&gt;Columnize&lt;/em&gt; menu type.&lt;/p&gt;

&lt;p&gt;This lets us create multiple columns, which we can individually populate with the content we wish to store inside a menu.&lt;/p&gt;

&lt;p&gt;You can directly navigate to the "Columnize Mega Menu Content" section to begin work. &lt;/p&gt;

&lt;p&gt;Like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zRXzo3RD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h3n98q9mt24n3gk2va6r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zRXzo3RD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h3n98q9mt24n3gk2va6r.png" alt="Columnize Mega Menu Content" width="880" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's take a look at what is happening here.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; In the Columnize tab, you can choose from any number of columns to show inside the mega menu. I have selected 3.&lt;/li&gt;
&lt;li&gt; The next step is to click the &lt;em&gt;Add menu&lt;/em&gt; button on any given column.&lt;/li&gt;
&lt;li&gt; Once you do that, you will be able to choose from any of your site content to add to that specific menu column.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The content can be anything. Blog posts, custom pages, categories, or any custom fields that you have on your WordPress site.&lt;/p&gt;

&lt;p&gt;Alternatively, if you wish to display content with images, you can do so by going back to &lt;strong&gt;Settings&lt;/strong&gt; and changing the &lt;em&gt;Type&lt;/em&gt; to &lt;strong&gt;Content Grid&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;How you wish to present your sites' navigation is entirely up to you.&lt;/p&gt;

&lt;h3&gt;
  
  
  Closing statement
&lt;/h3&gt;

&lt;p&gt;This also concludes our tutorial.&lt;/p&gt;

&lt;p&gt;As you can see, by using a plugin - adding a mega menu to a WordPress site is extremely easy. How you style it and how you wish to present it to your readers is entirely up to you.&lt;/p&gt;

</description>
      <category>wordpress</category>
    </item>
    <item>
      <title>How to Detect Mobile Browsers with JavaScript</title>
      <dc:creator>Alex Ivanovs</dc:creator>
      <pubDate>Wed, 09 Mar 2022 15:38:59 +0000</pubDate>
      <link>https://dev.to/stackdiary/how-to-detect-mobile-browsers-with-javascript-3a2l</link>
      <guid>https://dev.to/stackdiary/how-to-detect-mobile-browsers-with-javascript-3a2l</guid>
      <description>&lt;p&gt;Mobile detection has always been a crucial aspect of app development. It is relevant both for apps, but also software and websites. There are countless reasons to check for mobile browser agents. Most importantly, the ability to render a unique user experience.&lt;/p&gt;

&lt;p&gt;The UAParser.js library alone gets millions of weekly package downloads. And, in most cases, it is enough if you’re building something from scratch. But, what about alternative ways to detect mobile browsers with JavaScript?&lt;/p&gt;

&lt;p&gt;Sometimes you might just want a simple solution that does the job without any libraries. And in this article, I am gonna lay out for you a handful of JavaScript techniques for detecting mobile users. Let me know if I missed any!&lt;/p&gt;

&lt;h2&gt;
  
  
  navigator.userAgent
&lt;/h2&gt;

&lt;p&gt;The holy grain of browser detection is the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Navigator/userAgent"&gt;navigator.UserAgent&lt;/a&gt; property.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (/Android|iPhone/i.test(navigator.userAgent)) {
  // This checks if the current device is in fact mobile
}

// an alternative structure to check individual matches
if (
  navigator.userAgent.match(/Android/i) ||
  navigator.userAgent.match(/iPhone/i)
) {
  // making individual checks
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is, of course, a very primitive way of doing it. It can easily be manipulated as the User-Agent property can be spoofed. But, because it does the job you can still use it in a variety of projects.&lt;/p&gt;

&lt;p&gt;E.g. Landing pages or making a custom redirect to a mobile version.&lt;/p&gt;

&lt;h2&gt;
  
  
  TouchEvent
&lt;/h2&gt;

&lt;p&gt;One method to detect mobile users is to check if the device has a touch screen.&lt;/p&gt;

&lt;p&gt;Using the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/ontouchstart#browser_compatibility"&gt;GlobalEventHandlers.ontouchstart&lt;/a&gt; property you can make a simple check to see how the user interacted with your app. If the interaction came from a touch screen, you can then return a mobile version of the app or page.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if ("ontouchstart" in document.documentElement)
{
  // content for touch-screen (mobile) devices
}
else
{
  // everything else (desktop)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Touch-screen devices like Surface do not have this property. So, users coming from desktop-based touch devices will still see the desktop version of your pages.&lt;/p&gt;

&lt;h2&gt;
  
  
  Window.matchMedia()
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/matchMedia"&gt;Window.matchMedia()&lt;/a&gt; is one of the best properties for detecting mobile users with JavaScript. And it is so because it lets you interact with CSS directly.&lt;/p&gt;

&lt;p&gt;In a lot of cases, media queries are superior because they have built-in mobile detection tools. For example, you can make a call to check if “pointer:coarse” is true.&lt;/p&gt;

&lt;p&gt;This specific statement validates whether the device’s pointer is fine or coarse.&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;let isMobile = window.matchMedia("(pointer:coarse)").matches;&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;Alternatively, the device might have both a fine and coarse pointer. For this use case, we can check if any pointers are coarse.&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;let isMobile = window.matchMedia("(any-pointer:coarse)").matches;&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;Keep in mind that this only validates the query as true or false. A more refined way to check for mobile devices is to use media queries directly.&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;let isMobile = window.matchMedia("only screen and (max-width: 480px)").matches;&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;This query will directly check the max-width of the device and assert whether it matches the criteria. Again, this is quite a lot of work for getting all devices correctly. As such, it’s easier to use a pre-built library with all the devices types already defined.&lt;/p&gt;

&lt;h2&gt;
  
  
  Libraries for Detecting Mobile Devices
&lt;/h2&gt;

&lt;p&gt;For this section, I’m going to list the most popular JavaScript libraries for detecting mobile devices. Again, I emphasize that these are specific to JavaScript. Refer to the docs for proper implementation in your app.&lt;/p&gt;




&lt;h2&gt;
  
  
  UAParser.js
&lt;/h2&gt;

&lt;p&gt;As far as complete libraries go, UAParser is the best there is. With more than 10 million weekly downloads on &lt;a href="https://www.npmjs.com/package/ua-parser-js"&gt;npm&lt;/a&gt; alone – UAParser is the defacto solution for detecting mobile devices. As the name gives it away – the library works by parsing User-Agent strings.&lt;/p&gt;

&lt;p&gt;However, what makes it so popular is the fact that you can parse hundreds of device variations. And, all of it is very well documented. You can go from practical device vendors to more intricate detection patterns like CPU architecture.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/faisalman/ua-parser-js"&gt;GitHub&lt;/a&gt; &lt;a href="https://github.com/faisalman/ua-parser-js/blob/master/readme.md"&gt;Documentation&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  mobile-detect.js
&lt;/h2&gt;

&lt;p&gt;This is a fairly straightforward port of the Mobile Detect library for PHP, provided to the community by Heinrich Goebl. The library itself uses User-Agent for detection, so like we discussed earlier – not the best option.&lt;/p&gt;

&lt;p&gt;Still, it should do the job when it comes to practical HTML templates or portfolio projects.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/hgoebl/mobile-detect.js"&gt;GitHub&lt;/a&gt; &lt;a href="https://github.com/hgoebl/mobile-detect.js/blob/master/README.md"&gt;Documentation&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  isMobile
&lt;/h2&gt;

&lt;p&gt;Here we have another take on the User-Agent Navigator property from Kai Mallea. While still a simplistic solution, I like that isMobile provides a variety of specifications. For example, you can test for any mobile devices or specific ones like phone or tablet.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kaimallea/isMobile"&gt;GitHub&lt;/a&gt; &lt;a href="https://github.com/kaimallea/isMobile/blob/master/README.md"&gt;Documentation&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  react-device-detect
&lt;/h2&gt;

&lt;p&gt;Are you a &lt;a href="https://stackdiary.com/react-component-libraries/"&gt;React.js&lt;/a&gt; developer?&lt;/p&gt;

&lt;p&gt;Then this library from Michael Laktionov is for you. It works as you would expect – first the library detects device type, then renders the view based on that type. Works flawlessly with component integration, and can be further customized through API calls.&lt;/p&gt;

&lt;p&gt;One interesting fact is the number of selectors this library includes. It covers devices like smart TVs, wearables, a variety of iPhone devices, and much more. This gives you a broad selection of design choices when building an app for a specific device.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/duskload/react-device-detect"&gt;GitHub&lt;/a&gt; &lt;a href="https://github.com/duskload/react-device-detect/blob/master/README.md"&gt;Documentation&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>tutorial</category>
      <category>mobile</category>
    </item>
  </channel>
</rss>
