<?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: Adrian Guery</title>
    <description>The latest articles on DEV Community by Adrian Guery (@adrianguery).</description>
    <link>https://dev.to/adrianguery</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%2F709030%2F0d13742d-7e3d-45b3-897b-7032f120f13b.jpeg</url>
      <title>DEV Community: Adrian Guery</title>
      <link>https://dev.to/adrianguery</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/adrianguery"/>
    <language>en</language>
    <item>
      <title>Debugging Query Time in Gatsby: Identifying and Optimizing Long-Running Queries</title>
      <dc:creator>Adrian Guery</dc:creator>
      <pubDate>Mon, 03 Apr 2023 06:30:00 +0000</pubDate>
      <link>https://dev.to/adrianguery/debugging-query-time-in-gatsby-identifying-and-optimizing-long-running-queries-97b</link>
      <guid>https://dev.to/adrianguery/debugging-query-time-in-gatsby-identifying-and-optimizing-long-running-queries-97b</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Gatsby is a powerful React-based framework, enabling developers to build fast and optimized web applications. One of Gatsby's core features is its ability to combine data from multiple sources and transform it into a unified GraphQL API for querying. However, as your application grows, you may encounter long-running queries that slow down your build times and negatively impact performance.&lt;/p&gt;

&lt;p&gt;In this article, we'll discuss how to identify and optimize long-running queries in Gatsby using the &lt;code&gt;reportLongRunningQueryJob&lt;/code&gt; function. By the end of this guide, you'll be able to debug query time issues and improve the overall performance of your Gatsby application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Identifying Long-Running Queries
&lt;/h2&gt;

&lt;p&gt;Gatsby internally uses a function called &lt;code&gt;reportLongRunningQueryJob&lt;/code&gt; to log queries that take a long time to execute. You can modify this function directly in your &lt;code&gt;node_modules&lt;/code&gt; folder to log the longest-running queries and identify them. Here's how:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Locate the &lt;code&gt;reportLongRunningQueryJob&lt;/code&gt; function in your Gatsby project's &lt;code&gt;node_modules&lt;/code&gt; folder. The exact file path may vary depending on your Gatsby version, but it should be something like &lt;code&gt;node_modules/gatsby/dist/utils/reporter/report.js&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open the file in your favorite code editor and look for the following function:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&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;reportLongRunningQueryJob&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;queryJob&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Modify the function to log the query job details. For example, you can add a &lt;code&gt;console.log&lt;/code&gt; statement to print out the query, duration, and other relevant information:
&lt;/li&gt;
&lt;/ol&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;reportLongRunningQueryJob&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;queryJob&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&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;Long-running query:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="na"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;queryJob&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="na"&gt;duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;queryJob&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;duration&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="na"&gt;componentPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;queryJob&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;componentPath&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;ol&gt;
&lt;li&gt;Save the file and run your Gatsby application. You should now see console logs for any long-running queries, allowing you to identify them and analyze their performance.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Creating a Document to Track Long-Running Queries
&lt;/h2&gt;

&lt;p&gt;In addition to logging query details in the console, you may want to create a document that lists your longest-running queries for easier tracking and optimization. To do this, follow these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Create a new file in your Gatsby project's root folder named &lt;code&gt;long-running-queries.md&lt;/code&gt; (or any other name you prefer).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modify the &lt;code&gt;reportLongRunningQueryJob&lt;/code&gt; function in your &lt;code&gt;node_modules&lt;/code&gt; folder again, this time to append the query details to the document you created:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;   &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;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="s2"&gt;fs&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;path&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="s2"&gt;path&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

   &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;reportLongRunningQueryJob&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;queryJob&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&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;logEntry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`
Long-running query:
  Query: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;queryJob&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
  Duration: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;queryJob&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;duration&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;ms
  Component path: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;queryJob&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;componentPath&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;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;appendFileSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&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;long-running-queries.md&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;logEntry&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;ol&gt;
&lt;li&gt;Save the file and run your Gatsby application. Now, any long-running queries will be logged to the &lt;code&gt;long-running-queries.md&lt;/code&gt; document, allowing you to track and optimize them more easily.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Optimizing Long-Running Queries
&lt;/h2&gt;

&lt;p&gt;Once you've identified your long-running queries, you can take various steps to optimize them and improve your application's performance. Some optimization techniques include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Limiting the amount of data fetched in a single query&lt;/li&gt;
&lt;li&gt;Reducing the complexity of your GraphQL queries&lt;/li&gt;
&lt;li&gt;Using Gatsby's built-in image optimizations (e.g., &lt;code&gt;gatsby-image&lt;/code&gt; or &lt;code&gt;gatsby-plugin-image&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Implementing pagination or lazy-loading for large lists of data&lt;/li&gt;
&lt;li&gt;Utilizing caching mechanisms for static or infrequently updated data&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Debugging query time in Gatsby is essential for maintaining optimal performance in your web applications. By modifying the &lt;code&gt;reportLongRunningQueryJob&lt;/code&gt; function and creating a document to track your longest-running queries, you can identify and optimize slow queries to improve your application's build times and overall performance. Keep an eye on your queries and make necessary adjustments as your project evolves to ensure that Gatsby remains a fast and efficient tool for your web development needs.&lt;/p&gt;

</description>
      <category>gatsby</category>
      <category>performance</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>How to Re-activate CSS Code Splitting in Gatsby</title>
      <dc:creator>Adrian Guery</dc:creator>
      <pubDate>Fri, 31 Mar 2023 06:30:00 +0000</pubDate>
      <link>https://dev.to/kezios/how-to-re-activate-css-code-splitting-in-gatsby-1bf5</link>
      <guid>https://dev.to/kezios/how-to-re-activate-css-code-splitting-in-gatsby-1bf5</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Gatsby, a popular static site generator built on React, has a default configuration that bundles all the CSS (Cascading Style Sheets) into one file. Although this configuration might work for small-scale projects, it could lead to performance issues on larger websites. In such cases, re-activating CSS code splitting can lighten the load on initial page load, thus significantly improving the performance of your Gatsby site.&lt;/p&gt;

&lt;p&gt;This article will take you through the process of re-activating CSS code splitting in Gatsby to help you optimize your site's performance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is CSS Code Splitting&lt;/strong&gt;?&lt;/p&gt;

&lt;p&gt;CSS code splitting is a technique that divides a single large CSS file into smaller chunks. These smaller chunks of CSS are then loaded only when required, resulting in a faster initial page load. By splitting your CSS code, you can ensure that only the necessary CSS is loaded for any given page, reducing the amount of data that needs to be downloaded.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Gatsby Deactivates CSS Code Splitting by Default&lt;/strong&gt;?&lt;/p&gt;

&lt;p&gt;Gatsby deactivates CSS code splitting by default for simplicity and to ensure a seamless developer experience. This decision reduces the complexity of managing multiple CSS files, making it easier for developers to build and maintain their websites. However, this configuration may not be the best choice for all projects, especially those with a large number of styles or pages.&lt;/p&gt;

&lt;p&gt;For large projects, bundling all the CSS into a single file can lead to a significant increase in the size of the initial page load, as the browser needs to download and parse the entire CSS file before rendering the page. This can result in slower page load times, which can negatively impact user experience and search engine rankings.&lt;/p&gt;

&lt;h2&gt;
  
  
  Re-activating CSS Code Splitting in Gatsby
&lt;/h2&gt;

&lt;p&gt;To re-activate CSS code splitting in Gatsby, you need to make use of a plugin called &lt;code&gt;gatsby-plugin-css-modules&lt;/code&gt;. This plugin allows you to use CSS Modules with your Gatsby project, which enables you to split your CSS code into smaller, more manageable pieces that can be loaded on-demand.&lt;/p&gt;

&lt;p&gt;Follow these steps to re-activate CSS code splitting in your Gatsby project:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Install&lt;/strong&gt; &lt;code&gt;gatsby-plugin-css-modules&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;First, you need to install the &lt;code&gt;gatsby-plugin-css-modules&lt;/code&gt; plugin. To do this, open your terminal and navigate to your Gatsby project's root directory. Then, run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save&lt;/span&gt; gatsby-plugin-css-modules
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command installs the plugin and adds it to your &lt;code&gt;package.json&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Configure&lt;/strong&gt; &lt;code&gt;gatsby-config.js&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;Next, open your &lt;code&gt;gatsby-config.js&lt;/code&gt; file, which is located in the root directory of your Gatsby project. You need to add the &lt;code&gt;gatsby-plugin-css-modules&lt;/code&gt; plugin to the &lt;code&gt;plugins&lt;/code&gt; array. Add the following code to your &lt;code&gt;gatsby-config.js&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`gatsby-plugin-css-modules`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Configure the plugin options, if required&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;// ...&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;3. Start using CSS Modules&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;Now that you've installed and configured the plugin, you can start using CSS Modules in your Gatsby project. To do this, rename your CSS files to have the &lt;code&gt;.module.css&lt;/code&gt; extension (e.g., &lt;code&gt;styles.module.css&lt;/code&gt;). This ensures that your CSS files are treated as CSS Modules.&lt;/p&gt;

&lt;p&gt;In your React components, import the CSS Modules as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;styles&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./styles.module.css&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;MyComponent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;heading&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Hello&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;World&lt;/span&gt;&lt;span class="o"&gt;!&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;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;MyComponent&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 example above, the &lt;code&gt;styles&lt;/code&gt; object contains the generated class names for your CSS classes, which you can use in your JSX markup.&lt;/p&gt;

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

&lt;p&gt;By re-activating CSS code splitting in your Gatsby project, you can improve the performance of your site and ensure a faster initial page load. By dividing your CSS code into smaller chunks and loading them on-demand, you can optimize the user experience for your visitors.&lt;/p&gt;

&lt;p&gt;Using the &lt;code&gt;gatsby-plugin-css-modules&lt;/code&gt; plugin, you can easily implement CSS code splitting in your Gatsby project and start enjoying the benefits of this optimization technique.&lt;/p&gt;

</description>
      <category>gatsby</category>
      <category>css</category>
      <category>webpack</category>
      <category>performance</category>
    </item>
    <item>
      <title>How I Fine-Tuned GPT-3 for My Automatic Video Tutorial Project</title>
      <dc:creator>Adrian Guery</dc:creator>
      <pubDate>Wed, 29 Mar 2023 06:31:00 +0000</pubDate>
      <link>https://dev.to/kezios/how-i-fine-tuned-gpt-3-for-my-automatic-video-tutorial-project-995</link>
      <guid>https://dev.to/kezios/how-i-fine-tuned-gpt-3-for-my-automatic-video-tutorial-project-995</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In a previous article, I introduced my automatic video tutorial project, which leverages the power of GPT-3 and Remotion.js to generate video tutorials based on a JSON input. To optimize my project, I fine-tuned GPT-3 to better understand the specific JSON format expected by my Remotion.js project. In this follow-up article, you will discover how I went through the fine-tuning process to improve the efficiency of my project.&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%2F39xo6wph537sbsle32md.gif" 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%2F39xo6wph537sbsle32md.gif" alt="Prompt to json"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Create multiple formatted JSON examples
&lt;/h2&gt;

&lt;p&gt;For my video tutorial generation project, I created a dataset consisting of numerous examples of correctly formatted JSON that match my project's structure as input. I focused on gathering examples covering a wide range of js coding topics to ensure that GPT-3 can generate JSON inputs for any coding tutorial I want to create using my Remotion-based program.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Preprocess the Data for My Project's JSON Format
&lt;/h2&gt;

&lt;p&gt;To fine-tune GPT-3 for my project, I preprocessed the collected data to ensure it's in the appropriate format. I tokenized the JSON data according to my project's structure and converted the tokens into input and output sequences that GPT-3 can understand, optimizing the model for my project's requirements.&lt;/p&gt;

&lt;p&gt;The format I used is as follows:&lt;br&gt;
&lt;code&gt;{    "prompt":"THE_PROMPT_EXAMPLE\n\n###\n\n",    "completion":"THE_COMPLETION_EXAMPLE###"}&lt;/code&gt;&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;    
&lt;/span&gt;&lt;span class="nl"&gt;"prompt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"How to make an animated button which scale when we click on it. Write an example and highlight interesting parts of the example.&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;###&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;    
&lt;/span&gt;&lt;span class="nl"&gt;"completion"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"{    'code':'&amp;lt;!-- HTML for the button --&amp;gt;&amp;lt;button class='animated-button'&amp;gt;Click me!&amp;lt;/button&amp;gt;&amp;lt;!-- CSS for the animation --&amp;gt;&amp;lt;style&amp;gt;.animated-button {/* other button styles */transition: transform 0.1s;transform-origin: center;}.animated-button:active {transform: scale(0.95);}&amp;lt;/style&amp;gt;', 'language': 'html',   'hihglightExaplainations':[       {          'highlight':'animated-button',          'explanation':'the button has a class of animated-button that is used to apply the animation styles'       },       {          'highlight':'transition',          'explanation':'The transition property is used to specify the duration of the animation'       },       {          'highlight':'transform-origin',          'explanation':'the transform-origin property is used to specify the point around which the button will scale'       },       {          'highlight':':active',          'explanation':'The :active pseudo-class is used to apply a style to the button when it is being clicked'       },       {          'highlight':':transform',          'explanation':'the transform property is used to scale the button down by 5%'       },       {          'highlight':':scale',          'explanation':'using the scale function'       }    ] }###"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 3: Fine-Tune GPT-3 for My Project
&lt;/h2&gt;

&lt;p&gt;With the preprocessed, I fine-tuned GPT-3.&lt;br&gt;
I installed OpenAI on cli : &lt;br&gt;
&lt;code&gt;pip install --upgrade openai&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;I exported my OpenAI API KEY :&lt;br&gt;
&lt;code&gt;export OPENAI_API_KEY="MYAPIKEY"&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
I prepared my data : &lt;br&gt;
&lt;code&gt;openai tools fine_tunes.prepare_data -f /dev/gtp3-fine-tuning/fine-tuning-for-remotion-tutos.jsonl&lt;/code&gt;          &lt;/p&gt;

&lt;p&gt;I fined tune the model : &lt;br&gt;
&lt;code&gt;openai api fine_tunes.create -t /dev/gtp3-fine-tuning/fine-tuning-for-remotion-tutos_prepared.jsonl -m davinci&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Evaluate and Iterate for My Project
&lt;/h2&gt;

&lt;p&gt;After fine-tuning GPT-3, I evaluated its performance on the validation set in the context of generating JSON inputs for my specific project. I repeated other tries of fine-tuning process until GPT-3 achieved the desired performance for generating JSON inputs suitable for my Remotion-based program.&lt;/p&gt;

&lt;h2&gt;
  
  
  Generate JSON Inputs for My Project 🚀😎
&lt;/h2&gt;

&lt;p&gt;Once I fine-tuned GPT-3 for my project, it became a powerful tool to generate JSON inputs for my coding tutorials project. By providing GPT-3 with a prompt, the model generates a JSON input that my Remotion program uses to create a video tutorial, streamlining my content creation process.&lt;/p&gt;

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

&lt;p&gt;Fine-tuning GPT-3 to understand my expected JSON format has significantly improved the efficiency of my video tutorial creation process using Remotion. By following the steps outlined in this article and integrating them with my project, I have successfully trained GPT-3 to generate JSON inputs for a wide range of coding tutorials, enabling me to produce video contents very swiftly and easily.&lt;/p&gt;

</description>
      <category>gpt3</category>
      <category>frontend</category>
      <category>beginners</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Remotion Deep Dive into the Automatic Video Tutorials on Coding with GPT-4 and Remotion</title>
      <dc:creator>Adrian Guery</dc:creator>
      <pubDate>Wed, 29 Mar 2023 06:30:00 +0000</pubDate>
      <link>https://dev.to/kezios/remotion-deep-dive-into-the-automatic-video-tutorials-on-coding-with-gpt-4-and-remotion-4hlg</link>
      <guid>https://dev.to/kezios/remotion-deep-dive-into-the-automatic-video-tutorials-on-coding-with-gpt-4-and-remotion-4hlg</guid>
      <description>&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%2Fsp1rz538ttxlkagur0lk.gif" 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%2Fsp1rz538ttxlkagur0lk.gif" alt="JSON to video"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In the previous article, I introduced the automatic video tutorials on coding, a project that leverages GPT-4 and Remotion to create video tutorials based on JSON inputs generated by GPT-4 fine tune model. In this article, we will focus on how I used the Remotion.js, &lt;em&gt;&lt;strong&gt;react-syntax-highlighter&lt;/strong&gt;&lt;/em&gt; library and the &lt;code&gt;getBoundingClientRect&lt;/code&gt; method to create the video tutorials.&lt;/p&gt;

&lt;p&gt;There is the project : &lt;br&gt;
&lt;a href="https://github.com/AdrianGuery/gpt4-gpt3-video-generation" rel="noopener noreferrer"&gt;https://github.com/AdrianGuery/gpt4-gpt3-video-generation&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Using Real Code: React-Syntax-Highlighter Library
&lt;/h2&gt;

&lt;p&gt;The react-syntax-highlighter library is a powerful tool that provides syntax highlighting for code snippets in React applications. I chose this library to display the code in the video tutorial project because it supports a wide range of programming languages and offers various customization options.&lt;/p&gt;

&lt;p&gt;After installing the library, I imported the necessary components and styles in the React application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;Prism&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;SyntaxHighlighter&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="s2"&gt;react-syntax-highlighter&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;atomDark&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="s2"&gt;react-syntax-highlighter/dist/esm/styles/prism&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;Next, I used the &lt;code&gt;SyntaxHighlighter&lt;/code&gt; component to display the code snippet from the JSON input. I passed the &lt;code&gt;language&lt;/code&gt; and &lt;code&gt;style&lt;/code&gt; props to customize the appearance of the code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;SyntaxHighlighter&lt;/span&gt;
  &lt;span class="nx"&gt;customStyle&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;100%&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;100%&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;20px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
  &lt;span class="nx"&gt;language&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;example4&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;language&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;atomDark&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;showLineNumbers&lt;/span&gt;
  &lt;span class="nx"&gt;wrapLines&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;wrapLongLines&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;code&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/SyntaxHighlighter&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Highlighting Code Snippets with getBoundingClientRect
&lt;/h2&gt;

&lt;p&gt;To highlight specific parts of the code snippet, I needed to create a rectangle that surrounds each highlighted code segment. I accomplished this using the &lt;code&gt;getBoundingClientRect&lt;/code&gt; method, which returns the size of an element and its position relative to the viewport.&lt;/p&gt;

&lt;p&gt;I created a function that finds the first and last words of the highlighted code segment and calculates the bounding rectangle surrounding them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;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="p"&gt;...&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;firstRect&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;firstElement&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;getBoundingClientRect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;lastRect&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;lastElement&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;getBoundingClientRect&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;firstRect&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;lastRect&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setCurrentHighlightProps&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;firstRect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;firstRect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;large&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;lastRect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;firstRect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;lastRect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;currentIndex&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, I used this function to create a rectangle for each highlighted code segment in the JSON input:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;currentIndex&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
  &lt;span class="nx"&gt;currentIndex&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;example4&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;highlightExplanations&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
  &lt;span class="nx"&gt;currentHighlightProps&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Highlight&lt;/span&gt;
        &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;currentHighlightProps&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;currentHighlightProps&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;large&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;currentHighlightProps&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;large&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Subtitle&lt;/span&gt;
        &lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;example4&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;highlightExplanations&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;currentIndex&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;explanation&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;)}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With these highlight bounds, I was able to generate video tutorials that not only display the code snippet, but also highlight and explain specific parts of the code.&lt;/p&gt;

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

&lt;p&gt;In this detailed walkthrough, we explored how we implemented the automatic video tutorials on coding project using GPT-4, Remotion, react-syntax-highlighter library, and the &lt;code&gt;getBoundingClientRect&lt;/code&gt; method with real code snippets. By combining these technologies, I was able to create a powerful tool that generates video tutorials based on JSON inputs, helping developers learn and understand code snippets more effectively.&lt;/p&gt;

</description>
      <category>gpt3</category>
      <category>webdev</category>
      <category>video</category>
      <category>remotion</category>
    </item>
    <item>
      <title>Prompt to Video with GPT-4 and React.js - Automatic video generation</title>
      <dc:creator>Adrian Guery</dc:creator>
      <pubDate>Wed, 29 Mar 2023 06:29:00 +0000</pubDate>
      <link>https://dev.to/kezios/prompt-to-video-with-gpt-4-and-reactjs-automatic-video-generation-50i5</link>
      <guid>https://dev.to/kezios/prompt-to-video-with-gpt-4-and-reactjs-automatic-video-generation-50i5</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;I always strive to create engaging and informative content. I'm convinced that one of the most effective ways to teach coding is through video tutorials. However, creating high-quality video tutorials from scratch can be time-consuming and labor-intensive. That's why I've developed a program that leverages the power of GPT-4 and Remotion (framework for creating videos programmatically using React.js) to &lt;strong&gt;automatically&lt;/strong&gt; generate video tutorials from just a prompt.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example of output video generated by a GPT prompt&lt;/strong&gt; :&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%2Facjr9y51q61zu5honou7.gif" 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%2Facjr9y51q61zu5honou7.gif" alt="React countdown timer video"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;In this article, I will discuss how my program works and how I fine-tuned GPT-3 to understand the expected JSON format, allowing it to generate detailed and accurate JSON inputs for any coding tutorial I want to create a video with and how I did it also with GPT-4.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating the Program with Remotion
&lt;/h2&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%2F2mtam9isv0atfrgvimp1.gif" 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%2F2mtam9isv0atfrgvimp1.gif" alt="JsonToVideoRemotion"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Remotion is a powerful library that allows developers to create videos programmatically using React. By feeding a JSON input (which will be created by my GPT4 fine tune model) to my program, I can generate a video tutorial explaining how the code works step-by-step.&lt;/p&gt;

&lt;p&gt;The JSON input I use for this program has a specific structure, which includes the code snippet, the language, and an array of highlight explanations. The highlight explanations contain the code segment and a brief explanation of what that particular code does.&lt;/p&gt;

&lt;p&gt;For example, here is a JSON input for a simple React countdown timer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;code:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"import React, { useState, useEffect } from 'react';&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;function CountdownTimer() {&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt; const [seconds, setSeconds] = useState(60);&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt; useEffect(() =&amp;gt; {&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt; const interval = setInterval(() =&amp;gt; {&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt; setSeconds(seconds - 1);&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt; }, 1000);&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt; return () =&amp;gt; clearInterval(interval);&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt; }, [seconds]);&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt; return (&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt; &amp;lt;div&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt; {seconds} seconds remaining&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt; &amp;lt;/div&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt; );&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;language:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"javascript"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;highlightExplanations:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="err"&gt;highlight:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"import React, { useState, useEffect } from 'react';"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="err"&gt;explanation:&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"This imports the required dependencies from the React library."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="err"&gt;highlight:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"const [seconds, setSeconds] = useState(60);"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="err"&gt;explanation:&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"This uses the `useState` hook to initialize the `seconds` state variable with a value of 60 and create a function to update its value, `setSeconds`."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="err"&gt;highlight:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"const interval = setInterval(() =&amp;gt; {"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="err"&gt;explanation:&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"This sets up an interval that will run the anonymous function inside every 1000 milliseconds (1 second)."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="err"&gt;highlight:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"setSeconds(seconds - 1);"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="err"&gt;explanation:&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"This decreases the value of the `seconds` state variable by 1 every time the interval runs."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="err"&gt;highlight:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"return () =&amp;gt; clearInterval(interval);"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="err"&gt;explanation:&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"This is the cleanup function for the `useEffect` hook. It clears the interval when the component unmounts to prevent memory leaks."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="err"&gt;highlight:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"{seconds} seconds remaining"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="err"&gt;explanation:&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"This displays the current value of the `seconds` state variable in the component's render output."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Upon receiving this JSON input, my program processes it and generates a video tutorial using Remotion. The video tutorial explains each part of the code snippet, as specified in the highlight explanations array.&lt;/p&gt;

&lt;p&gt;I wrote a more advanced article about this part : &lt;/p&gt;

&lt;h2&gt;
  
  
  Fine-tuning GPT-3 for JSON Input Generation
&lt;/h2&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%2Ffo2qbc24etvx40ouxe4y.gif" 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%2Ffo2qbc24etvx40ouxe4y.gif" alt="PromptGPT3FineTunedVideo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To make the process of creating video tutorials even more efficient, I fine-tuned GPT-3 to understand the specific JSON format used by my program. By training GPT-3 with numerous examples of correctly formatted JSON inputs, the model can now generate JSON inputs for any coding tutorial I want to create a video for.&lt;/p&gt;

&lt;p&gt;This means that I can simply ask GPT-3 with to generate a JSON input that my Remotion program can use to create a video tutorial.&lt;/p&gt;

&lt;p&gt;For example, I might ask GPT-3 to create a JSON input for a tutorial on how to create a simple countdown timer in React. GPT-3 would then generate a JSON input like the one shown earlier, with the code snippet and complete with highlight explanations for each part of the code snippet.&lt;/p&gt;

&lt;p&gt;I write an article explaining how I fine tune my GPT-3 model step by step :&lt;/p&gt;

&lt;h2&gt;
  
  
  Utilizing GPT-4 for JSON Input Generation by Providing Five Prompt-Answer Examples
&lt;/h2&gt;

&lt;p&gt;After gaining access to the GPT-4 API, I decided to experiment with GPT-4 as a JSON generator. The most significant advantage of GPT-4 is its extensive context capability, allowing for up to 50k tokens of context. This means that providing GPT-4 with five examples of prompt-answer pairs is possible, leading to improved results.&lt;/p&gt;

&lt;p&gt;As a result, the outcomes were even better than those achieved with the fine-tuned GPT-3 model, as there were fewer instances of incorrect JSON formats.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example : button which disappears when it's clicked
&lt;/h2&gt;

&lt;p&gt;We asked our fine-tuned GPT3 (or GPT-4) model to : &lt;br&gt;
&lt;em&gt;&lt;strong&gt;Create a tutorial which teach how to create a button which disappears when it's clicked&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It answers with this output :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;code:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;button id='disappearing-button'&amp;gt;Click me!&amp;lt;/button&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;#disappearing-button {&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt; display: block;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;#disappearing-button:active {&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt; display: none;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt; document.getElementById('disappearing-button').addEventListener('click', function() {&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt; this.style.display = 'none';&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt; });&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/script&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;language:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"html"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;highlightExplanations:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="err"&gt;highlight:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"display: block;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="err"&gt;explanation:&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"This sets the display property of the button to 'block', which makes it visible on the page."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="err"&gt;highlight:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"display: none;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="err"&gt;explanation:&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"This sets the display property of the button to 'none', which makes it hidden on the page."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="err"&gt;highlight:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"document.getElementById('disappearing-button')"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="err"&gt;explanation:&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"This gets a reference to the button element on the page by its ID."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="err"&gt;highlight:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"addEventListener('click', function()"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="err"&gt;explanation:&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"This sets up a click event listener on the button element, which means that the anonymous function inside will be executed when the button is clicked."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="err"&gt;highlight:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"this.style.display = 'none';"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="err"&gt;explanation:&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"Inside the event listener function, 'this' refers to the element that the event listener is attached to (in this case, the button element). Setting the 'display' property of this element to 'none' makes it hidden on the page."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which, once interpreted by Remotion will output this video tutorial : &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%2F7dez3n0xz1h8zmnlfprb.gif" 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%2F7dez3n0xz1h8zmnlfprb.gif" alt="button which disappears video"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;By combining the power of GPT-4 (or fine tuned GPT-3) and Remotion, I have created a program that can automatically generate video tutorials for a wide range of coding topics. That shows how a NLP model can produce visual content with another program.&lt;/p&gt;

&lt;p&gt;As AI and machine learning continue to advance, the possibilities for automating content creation in various fields are endless. This program is just one example of how we can harness AI to revolutionize the way we create content.&lt;/p&gt;

</description>
      <category>gpt4</category>
      <category>gpt3</category>
      <category>chatgpt</category>
      <category>react</category>
    </item>
    <item>
      <title>Mastering the Github Search Engine to Find Code Examples for Complex Integrations</title>
      <dc:creator>Adrian Guery</dc:creator>
      <pubDate>Mon, 20 Mar 2023 18:42:55 +0000</pubDate>
      <link>https://dev.to/kezios/mastering-the-github-search-engine-to-find-code-examples-for-complex-integrations-573e</link>
      <guid>https://dev.to/kezios/mastering-the-github-search-engine-to-find-code-examples-for-complex-integrations-573e</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Github is a powerful platform for software development, providing a collaborative environment for countless repositories. Its search engine is a potent tool that can significantly enhance your productivity and help you find solutions when documentation falls short or with new technologies not already well documented. In this article, we will explore how to use Github's search engine effectively to find code examples for complex integrations.&lt;/p&gt;

&lt;p&gt;As Catalin Pit, once said, "Documentations without examples are killing me. I read the documentation and then spend 30 minutes on Google trying to find how to do something from the documentation. Please add examples where possible!". He is right, this sentiment resonates with many developers, including me, who struggle to comprehend complex concepts from documentation alone. That's when the Github search engine comes to the rescue.&lt;br&gt;
&lt;a href="https://twitter.com/catalinmpit/status/1488506699296215040" rel="noopener noreferrer"&gt;https://twitter.com/catalinmpit/status/1488506699296215040&lt;/a&gt;&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%2Fvjepidnsi3e348sm8jts.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%2Fvjepidnsi3e348sm8jts.png" alt="Documentations without examples tweet"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Power of Github Search Engine
&lt;/h2&gt;

&lt;p&gt;The Github search engine can help developers find repositories, code, issues, users, and more. It supports a variety of search filters, qualifiers, and sorting options, making it easy to find what you need. By leveraging the search engine effectively, you can discover numerous examples and solutions shared by the vast Github community.&lt;/p&gt;

&lt;p&gt;Here are some tips to help you get the most out of the Github search engine:&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Use Specific Code Snippets
&lt;/h2&gt;

&lt;p&gt;Instead of searching with sentences, use specific code snippets as your search query. For example, if you're unsure about a function's parameters in a library, search for the function name followed by an opening parenthesis, like "thatFunction(". This can provide you with relevant results that help you understand how the function works and its various parameters.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Utilize Search Qualifiers
&lt;/h2&gt;

&lt;p&gt;Github search engine supports a range of search qualifiers that can help you refine your search results. Some common qualifiers include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;in:file&lt;/code&gt;: Searches for a specific keyword or phrase within a file's content.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;extension:ext&lt;/code&gt;: Filters results by file extension.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;language:lang&lt;/code&gt;: Filters repositories by programming language.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;user:username&lt;/code&gt;: Searches repositories owned by a specific user.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;org:organization&lt;/code&gt;: Searches repositories within a specific organization.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, if you want to find examples of Python code that uses the Flask framework, you can search for "Flask in:file language:Python".&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Use Advanced Search Syntax
&lt;/h2&gt;

&lt;p&gt;In addition to qualifiers, Github search engine supports advanced search syntax, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Quotation marks (""): Use quotes to search for an exact phrase.&lt;/li&gt;
&lt;li&gt;Asterisk (*): Use an asterisk as a wildcard to match any character sequence.&lt;/li&gt;
&lt;li&gt;Minus (-): Use a minus sign to exclude specific keywords or qualifiers from your search.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For instance, if you want to find examples of React integration without Redux, you can search for "React integration example -Redux".&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Sort and Filter Results
&lt;/h2&gt;

&lt;p&gt;By default, Github search results are sorted by the "Best match", which takes into account factors such as relevance, user engagement, and recency. However, you can also sort results by the number of stars, forks, or the date of the most recent update which is very interesting if the example you search is about recent version of a library.&lt;/p&gt;

&lt;p&gt;Moreover, you can filter results by the type of content (repositories, code, issues, etc.), language, and other criteria. This helps you narrow down the results to find the most relevant examples and solutions.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Explore Related Repositories and Users
&lt;/h2&gt;

&lt;p&gt;When you find a useful example or solution, take the time to explore the repository and the user who created it. You might find additional examples, documentation, or resources that can help you with your integration.&lt;/p&gt;

&lt;p&gt;Furthermore, follow users and organizations that frequently share valuable examples and solutions. This way, you can stay updated on the latest best practices and discoveries in your field.&lt;/p&gt;

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

&lt;p&gt;The Github search engine is an invaluable resource for developers seeking examples and solutions for complex integrations. By mastering the search engine's features, you can save time and effort in finding the information you need. Don't let insufficient documentation hold you back – harness the power of the Github search engine to find examples and inspiration from the vast community of developers. Happy coding!&lt;/p&gt;

</description>
      <category>documentation</category>
      <category>github</category>
      <category>webdev</category>
      <category>tips</category>
    </item>
    <item>
      <title>5 ultra actionable tips to improve your Web performances</title>
      <dc:creator>Adrian Guery</dc:creator>
      <pubDate>Sat, 15 Oct 2022 10:18:30 +0000</pubDate>
      <link>https://dev.to/kezios/5-ultra-actionable-tips-to-improve-your-web-performances-219p</link>
      <guid>https://dev.to/kezios/5-ultra-actionable-tips-to-improve-your-web-performances-219p</guid>
      <description>&lt;p&gt;If you want your website to be successful and well ranking on Google, you need to make sure it loads quickly and efficiently. Web performance is a measure of how fast a web page loads and how well it responds to user input. There are a number of factors that can affect web performance, including file size, server response time, and code efficiency. In this post, I will give you some tips on how to improve web performance and make your site run faster.&lt;br&gt;
It's in part how we optimize our website to have 100% pagespeed on Google : &lt;a href="https://www.kezios.fr/"&gt;https://www.kezios.fr/&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  1 - Improve your Images
&lt;/h2&gt;

&lt;p&gt;Lazy loading images is a technique that lets you load the images only when a user scrolls the page. This means that if a user doesn’t reach the end of the page, they won’t load any images at all.&lt;/p&gt;

&lt;p&gt;Decoding an image means converting it into a format that can be displayed on your site. The process is done by your browser, and it takes some time to do so. To prevent this process from happening as multiple times, it is better to decode them once and then store them for later use. Do not display over quality images&lt;/p&gt;

&lt;p&gt;Images have different formats such as PNG, JPEG, GIF etc., which are used according to their needs and purposes but sometimes we use the wrong format for our image which makes them look blurry or pixelated in browsers. A simple trick which you can use here is giving proper dimensions and in multiple format (webp &amp;amp; jpg) for each image so that it will display properly even if there are differences between users’ screen and browser.&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;picture&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;source&lt;/span&gt; &lt;span class="na"&gt;srcset&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"assets/img/yourImage.webp"&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"image/webp"&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;source&lt;/span&gt; &lt;span class="na"&gt;srcset&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"assets/img/yourImage.jpg"&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"image/jpeg"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; 
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;img&lt;/span&gt; &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"assets/img/yourImage.jpg"&lt;/span&gt; &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Your image !"&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;picture&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2 - Preload &amp;amp; prefetch
&lt;/h2&gt;

&lt;p&gt;Preloading is a technique used by web browsers to load ressources more quickly. It typically involves loading images and JavaScript files before a user has requested them, thus reducing the amount of time it takes to load the page.&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;link&lt;/span&gt; &lt;span class="na"&gt;rel&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"preload"&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"yourJsFile.js"&lt;/span&gt; &lt;span class="na"&gt;as&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"script"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Prefetch can also be used to add value to your website by prefetching some of the content they will view at a later point in time. This is especially useful for to prefetch files which will be use in the next view page.&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;link&lt;/span&gt; &lt;span class="na"&gt;rel&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"prefetch"&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"yourJsFile.js"&lt;/span&gt; &lt;span class="na"&gt;as&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"style"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3 - Minified and Compressed your ressources
&lt;/h2&gt;

&lt;p&gt;Minification is the process of removing unnecessary characters from source code without changing its functionality. The most common way to do this is to remove white space and other formatting characters, but it can also include shortening variable names, merging multiple statements into one, or other alterations.&lt;/p&gt;

&lt;p&gt;Compression is the process of reducing the size of a file. There are a few different methods for compressing files; these are defined in RFC 1952 as DEFLATE (the default compression method for GZIP) as well as BZIP2, LZMA/LZMA2 and XZ. &lt;/p&gt;

&lt;h2&gt;
  
  
  4 - CDN served your ressources and use a caching system
&lt;/h2&gt;

&lt;p&gt;A content delivery network or CDN is a large distributed system of servers deployed in multiple data centers across the Internet. The goal of a CDN is to serve content to end users with high availability and high performance.&lt;/p&gt;

&lt;p&gt;Caching systems are used in web performances to improve the speed and responsiveness of the system. Caching systems store frequently accessed data in a fast access memory, so that it can be quickly retrieved when needed. This can improve the performance of the system by reducing the amount of time needed to access the data.&lt;/p&gt;

&lt;h2&gt;
  
  
  5 - Optimized your fonts
&lt;/h2&gt;

&lt;p&gt;One way to improve web performance is by optimizing the fonts. This can be done by reducing the number of font faces, using font faceobserver to load fonts asynchronously, and using font-display to control how the browser renders the font. By doing this, the browser can render the page faster and the user can see the content sooner.&lt;/p&gt;

</description>
      <category>performance</category>
      <category>webdev</category>
      <category>seo</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Advantages of SSG over SSR</title>
      <dc:creator>Adrian Guery</dc:creator>
      <pubDate>Thu, 12 May 2022 09:31:20 +0000</pubDate>
      <link>https://dev.to/kezios/advantages-of-ssg-over-ssr-3na</link>
      <guid>https://dev.to/kezios/advantages-of-ssg-over-ssr-3na</guid>
      <description>&lt;p&gt;We will see in this article why you should use SSG over SSR.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Well, don't take this for a generalization&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  1.Performance
&lt;/h2&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%2Fp326wr53gebw53dw7tg2.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%2Fp326wr53gebw53dw7tg2.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The server doesn't have to do anything except deliver the HTML to the client. Because of this, for users with a slow connection, it's a much faster experience to load a static site than it is to load a server-side rendered (SSR) site because the content has already been processed.&lt;/p&gt;

&lt;p&gt;Static sites are also fast, even if the origin is slow. This is because there's no processing required on the origin for static sites—it just has to fetch and deliver the file.&lt;/p&gt;

&lt;p&gt;Static sites improve time to first byte (TTFB). TTFB is an important metric that shows how fast your site begins loading in users' browsers—the lower this number, the better. This metric is influenced by many factors including latency, caching, and processing on subsequent requests. Because there's no server-side processing required when using SSGs, they give you instant TTFB and therefore better web core vitals scores from Google Lighthouse.&lt;/p&gt;

&lt;h2&gt;
  
  
  2.Build Time error catching
&lt;/h2&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%2Fttlq76mwb1ewps2q34rm.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%2Fttlq76mwb1ewps2q34rm.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One of the biggest advantages of SSG is the ability to do build time error-catching. If you've ever used a CSS preprocessor, you'll be familiar with this concept: if you make a mistake in your code and try to compile it, you'll get an error. This is because these preprocessors are running on the client side and are not actually compiling anything.&lt;/p&gt;

&lt;h2&gt;
  
  
  3.Resilience
&lt;/h2&gt;

&lt;p&gt;The advantages of static site generators (SSGs) over server-side rendering (SSR) are numerous, but there is one that stands out to me. It's about resilience. While a server-rendered site is dependent on the API, a static site generator doesn't care. If your API goes down, your page will still display the data that was fetched at build time.&lt;/p&gt;

&lt;p&gt;For example, if you have an API like NASA's Astronomy Picture of the Day API, and it goes down for some reason on Christmas or New Years Day or the Super Bowl or whatever day it is that you're having lots of traffic, your site will still work because it has all the data it needs in its own files and directories. The only thing that won't work is rehydration—your page won't be able to fetch new pictures after the initial render. But at least your users will still see something!&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Simpler caching logic
&lt;/h2&gt;

&lt;p&gt;First of all, with SSG simpler caching logic is possible. On my site, I cache the generated HTML on a CDN and only regenerate it when one of my markdown files changes. This allows me to have a very fast page load time even on mobile devices despite hosting the site on a small server with no CDN in front of it.&lt;/p&gt;

&lt;p&gt;With SSG you can boost performance using CDN caching without a lot of extra configuration. If you have a static site with 50 pages, you can put them all on a CDN and serve them from there instead of your own server, which helps your page load time tremendously—but if you update one of those pages, you need to invalidate that cached version on your CDN. If every page has its own cache-control header, this is easy&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Less infra complexity
&lt;/h2&gt;

&lt;p&gt;SSG is a simpler architecture, with fewer moving parts. It’s also significantly less expensive to run, since you don’t have to pay for the redundant upkeep of multiple servers.&lt;/p&gt;

&lt;p&gt;SSGs are also cloud agnostic. You can host them on any cloud provider you like and they will continue to work as advertised.&lt;/p&gt;

&lt;p&gt;The security posture of having one less server to worry about is another big benefit. If an SSG is compromised, it only has access to its own data, not anything else on your network or in your environment.&lt;/p&gt;

&lt;p&gt;Infinite scale is another major advantage. As long as you have enough capacity on your web server to handle the initial traffic spike, you can add more web servers without worrying about where to put them or how much bandwidth they will consume.&lt;/p&gt;

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

&lt;p&gt;There is the lot of advantages why you should use SSG over SSR. And we see only few, there is a lot more.&lt;br&gt;
But when we start developing a web-application, it's become clear that there is no universal solution. We need to make the decision depending on our project, and should always weigh all aspects carefully. Sometimes SSR will be more advantages than SSG ! &lt;/p&gt;

</description>
      <category>ssg</category>
      <category>gatsby</category>
      <category>nextjs</category>
      <category>performance</category>
    </item>
    <item>
      <title>Code splitting in Gatsby</title>
      <dc:creator>Adrian Guery</dc:creator>
      <pubDate>Mon, 02 May 2022 07:57:40 +0000</pubDate>
      <link>https://dev.to/kezios/code-splitting-in-gatsby-2833</link>
      <guid>https://dev.to/kezios/code-splitting-in-gatsby-2833</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This article will be especially interesting for large Gatsby projects: +1,000 pages.&lt;br&gt;
Also if your project uses React18 or +, use this method instead : &lt;a href="https://youtu.be/lypEGNEIRKE"&gt;https://youtu.be/lypEGNEIRKE&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Gatsby is a very powerful meta framework for developing very quick loading sites. Which is very important for SEO and for UX.&lt;/p&gt;

&lt;p&gt;With the generation of static pages of Gatsby, the TTFB (time to first byte) and the FCP (first contentful paint) are lowered a lot compared to a CSR site (client side rendering) resulting for instance from a React pure development. And with the optimization of picture loading, with Gatsby Image, comes as well the optimisation of the LCP.&lt;/p&gt;

&lt;p&gt;And all this is done almost automatically with Gatsby! Incredible ! Nothing's left? Not really 😅 It would have been too easy.&lt;/p&gt;

&lt;p&gt;The more your project grows, the more likely you will load more JS bundles than needed in some pages of your site. If you perform a test using PageSpeed Insights (&lt;a href="https://pagespeed.web.dev/"&gt;pagespeed.web.dev&lt;/a&gt;) you may get this advice / opportunity to optimize your page :&lt;/p&gt;

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

&lt;p&gt;This optimization opportunity occurs when you load javascript code that is not used by the page on which you are performing the test.&lt;/p&gt;

&lt;p&gt;There are two main causes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;bad code splitting&lt;/li&gt;
&lt;li&gt;third party scripts: GTM, Facebook pixels, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this article, we will see how to fix the main cause of this problem, &lt;em&gt;&lt;strong&gt;bad code splitting&lt;/strong&gt;&lt;/em&gt;. The second cause will be discussed in a second article.&lt;/p&gt;

&lt;h2&gt;
  
  
  How does Gatsby split your code natively?
&lt;/h2&gt;

&lt;p&gt;Initially, Gatsby organize your JS bundles into 3 categories:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;application-level chunks (shared with all pages),&lt;/li&gt;
&lt;li&gt;template-level chunks (shared with all pages of the same template),&lt;/li&gt;
&lt;li&gt;page-level data imports&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's take the example of a news site that creates articles for each news, some having videos. &lt;/p&gt;

&lt;p&gt;Our site has several page templates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Home page template&lt;/li&gt;
&lt;li&gt;News page template (potentially with videos depending on the news)&lt;/li&gt;
&lt;li&gt;News categories page template (which lists and organizes news depending on their category)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We will focus on the news pages, which are the most important on the site. The specificity of our news pages is that they potentially have videos.&lt;br&gt;
Therefore we need a library allowing a good management of these videos. Let's take &lt;strong&gt;Video.js&lt;/strong&gt; for example. This library is perfect, it allows us to play videos in many formats (MP4, Webm, HLS, DASH, etc.) and it implements an easy way to customize our video player.&lt;/p&gt;

&lt;p&gt;The problem with this library is that it’s heavy, 573.6kb MINIFIED, and 159.1 kB MINIFIED + GZIPPED.&lt;/p&gt;

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

&lt;p&gt;According to &lt;a href="https://bundlephobia.com/package/video.js@7.18.1"&gt;bundlephobia&lt;/a&gt;, it can take up to 3.18 seconds to load in slow 3G. This can seriously spoil the experience of our site, which aims to be efficient and quick to load (which is why we decided to develop it with Gatsby).&lt;/p&gt;

&lt;p&gt;Now we will check the bundles of our articles without videos, to see if they have also the Video.js imported. &lt;/p&gt;
&lt;h2&gt;
  
  
  How to analyze the bundles of each pages in Gatsby ?
&lt;/h2&gt;

&lt;p&gt;Thanks to the &lt;strong&gt;gatsby-plugin-perf-budgets&lt;/strong&gt; and &lt;strong&gt;gatsby-plugin-webpack-bundle-analyse-v2&lt;/strong&gt; plugins which are installed using this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i gatsby-plugin-webpack-bundle-analyser-v2 -D
npm i gatsby-plugin-perf-budgets -D
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can see that our video library (&lt;strong&gt;Video.js&lt;/strong&gt;) is loaded in all article pages, even if they don't have videos.&lt;/p&gt;

&lt;p&gt;Bundle analyze of a page article without video :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kUfgmGRn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x7fzexevqgpf9x49ye2c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kUfgmGRn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x7fzexevqgpf9x49ye2c.png" alt="Bundle analyze before code splitting" width="880" height="679"&gt;&lt;/a&gt;&lt;br&gt;
And we import 457 kb of JS : &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AU_uUzaU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q3f0xgppqowwiw84yr7s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AU_uUzaU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q3f0xgppqowwiw84yr7s.png" alt="Bundles size import before code splitting" width="740" height="242"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I simplified the rendering of the analysis to make it more readable (Yes I'm a photoshop master)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That’s where &lt;em&gt;&lt;strong&gt;code splitting&lt;/strong&gt;&lt;/em&gt; sets in : we basically split the import of our &lt;em&gt;&lt;strong&gt;VideoPlayer&lt;/strong&gt;&lt;/em&gt; component (which itself imports and uses our &lt;strong&gt;Video.js&lt;/strong&gt; library).&lt;/p&gt;
&lt;h2&gt;
  
  
  How to do code splitting with Gatsby?
&lt;/h2&gt;

&lt;p&gt;Once we have identified what code to split by analysing the different bundles of the pages, we are able to code split the components containing the packages that we want to import only on page with videos : in our example, the &lt;strong&gt;VideoPlayer&lt;/strong&gt; component.&lt;/p&gt;

&lt;p&gt;To do so with Gatsby, complementary packages are needed :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;@loadable/babel-plugin&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;@loadable/component&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;@loadable/webpack-plugin&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gatsby-plugin-loadable-components-ssr&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And add the &lt;code&gt;gatsby-plugin-loadable-components-ssr&lt;/code&gt; plugin that we just installed to our plugin list in the &lt;code&gt;gatsby-config.js&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Then we just have to use &lt;code&gt;@loadable/component&lt;/code&gt; to import our VideoPlayer component:&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;loadable&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@loadable/component&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;VideoPlayer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;loadable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;~/components/VideoPlayer/VideoPlayer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then make sure to &lt;strong&gt;conditionally&lt;/strong&gt; use the &lt;strong&gt;&lt;em&gt;VideoPlayer&lt;/em&gt;&lt;/strong&gt; component only if the article has a video:&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="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;article&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;video&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;VideoPlayer&lt;/span&gt;
        &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;article&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;video&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;article&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;video&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;intro&lt;/span&gt;&lt;span class="si"&gt;}&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And so, now our pages without videos no longer have the &lt;strong&gt;&lt;em&gt;Video.js&lt;/em&gt;&lt;/strong&gt; library in their bundles:&lt;/p&gt;

&lt;p&gt;(Always the same photoshop talents)&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DbsYnyXn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o2alq7qqe0gblzckxenm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DbsYnyXn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o2alq7qqe0gblzckxenm.png" alt="Bundle analyze after code splitting" width="880" height="676"&gt;&lt;/a&gt;&lt;br&gt;
Now we import 355kb of JS files, and we economize 2 requests!&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0UGEkZtn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ix12u06iddd4hyqj5mjx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0UGEkZtn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ix12u06iddd4hyqj5mjx.png" alt="Bundles size import after code splitting" width="678" height="184"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Voilà, you have just seen how to create code splitting with Gatbsy. &lt;/p&gt;

&lt;p&gt;But you should know that with React 18 and &lt;strong&gt;React.lazy()&lt;/strong&gt;, it's now possible to create splitting code natively! Without the &lt;code&gt;gatsby-plugin-loadable-components-ssr&lt;/code&gt; plugin ! So moving to React 18 seems then to be a good alternative.&lt;/p&gt;

&lt;p&gt;I put here a list of some reliable sources to deepen what we have just seen together if you are interested:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.gatsbyjs.com/docs/how-to/performance/improving-site-performance/#step-1-profile-your-bundle"&gt;https://www.gatsbyjs.com/docs/how-to/performance/improving-site-performance/#step-1-profile-your-bundle&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.slideshare.net/calcsam/the-anatomy-of-a-performance-audit/29"&gt;https://www.slideshare.net/calcsam/the-anatomy-of-a-performance-audit/29&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>gatsby</category>
      <category>webpack</category>
      <category>performance</category>
    </item>
    <item>
      <title>Fallback Client side route in Gatsby</title>
      <dc:creator>Adrian Guery</dc:creator>
      <pubDate>Mon, 07 Feb 2022 09:55:17 +0000</pubDate>
      <link>https://dev.to/kezios/fallback-client-side-route-in-gatsby-40o0</link>
      <guid>https://dev.to/kezios/fallback-client-side-route-in-gatsby-40o0</guid>
      <description>&lt;h2&gt;
  
  
  What is a Fallback Client side route ?
&lt;/h2&gt;

&lt;p&gt;Because the sites created with Gatsby.js are static sites, which is highly optimized from a performance point of view, for the content to be accessible, the site must be built since this content is available (from the CMS or the back-end).&lt;/p&gt;

&lt;p&gt;But in some cases, especially large content sites, content are add by the editorial team  faster than builds are done. And so, some content is added (via the CMS or the back-end), but not yet available on the site.&lt;/p&gt;

&lt;p&gt;But this problem is adjustable thanks to a “&lt;strong&gt;&lt;em&gt;Fallback Client side route”&lt;/em&gt;&lt;/strong&gt; system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use case : News website
&lt;/h2&gt;

&lt;p&gt;On our news site, we have more than &lt;strong&gt;10,000 articles&lt;/strong&gt;, they are stored in a database, and we create static pages using the Gatsby's &lt;strong&gt;createPages&lt;/strong&gt; API.&lt;/p&gt;

&lt;p&gt;So we have, for example, articles with these following urls:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;articles/news/AZE123&lt;/li&gt;
&lt;li&gt;articles/hobbies/RTY345&lt;/li&gt;
&lt;li&gt;articles/tips/UIO433&lt;/li&gt;
&lt;li&gt;articles/tips/QSD345&lt;/li&gt;
&lt;li&gt;articles/hobbies/FGH678&lt;/li&gt;
&lt;li&gt;articles/news/JKL789&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The articles are added to the database after their creations by the team of journalists. Every day, the team of journalists on the site write an average of 100 articles and want to make them &lt;strong&gt;immediately&lt;/strong&gt; accessible, because they talk about instant actuality subjects.&lt;/p&gt;

&lt;p&gt;But the site is only rebuild 15 times a day (or else it takes several ten minutes to rebuild) → This is a part of what we called the &lt;strong&gt;JAMTAX&lt;/strong&gt; (in reference to the JAMSTACK). So, very often, it happens that articles, which have just been published, are not accessible instantly, but only after multiple minutes or even hours.&lt;/p&gt;

&lt;p&gt;It’s so necessary to create a “&lt;strong&gt;&lt;em&gt;Fallback Client side route”&lt;/em&gt;&lt;/strong&gt;. This &lt;strong&gt;&lt;em&gt;Fallback Client side route&lt;/em&gt;&lt;/strong&gt; will be the route that will be used until the article has been statically generated. This &lt;strong&gt;&lt;em&gt;Fallback Client side route&lt;/em&gt;&lt;/strong&gt; will be generated on the client side thanks to a call to the API.&lt;/p&gt;

&lt;h1&gt;
  
  
  How to setup a “Fallback Client side route” in Gatsby?
&lt;/h1&gt;

&lt;p&gt;Our &lt;strong&gt;&lt;em&gt;Fallback Client side route&lt;/em&gt;&lt;/strong&gt; will &lt;em&gt;match&lt;/em&gt; with URL of this following shape : &lt;strong&gt;&lt;em&gt;articles/:articleType/:articleId&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And if the client want to access to an article that has been generated statically, he must have access to the static page (SSG) and not the &lt;strong&gt;&lt;em&gt;Fallback Client side route&lt;/em&gt;&lt;/strong&gt;, because it’s more optimised.&lt;/p&gt;

&lt;p&gt;For this we create a page which will be this &lt;strong&gt;&lt;em&gt;Fallback Client side&lt;/em&gt;&lt;/strong&gt;, then thanks to the &lt;strong&gt;&lt;em&gt;onCreatePage&lt;/em&gt;&lt;/strong&gt; API and its &lt;strong&gt;&lt;em&gt;matchPath&lt;/em&gt;&lt;/strong&gt; argument, we will be able to redefine its matchPath when it is created :&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="nx"&gt;actions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createPage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;matchPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;articles/:articleType/:articleId&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fallbackArticlesComponent.tsx&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;//The necessary context for your template&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;So, all users who want to access pages with the shape &lt;strong&gt;&lt;em&gt;articles/:articleType/:articleId,&lt;/em&gt;&lt;/strong&gt; and for which there is no statically generated page, have access to the content of this &lt;strong&gt;fallback page&lt;/strong&gt; (and therefore of the &lt;strong&gt;&lt;em&gt;fallbackArticlesComponent.tsx&lt;/em&gt;&lt;/strong&gt; component) .&lt;/p&gt;

&lt;p&gt;So, we need to make a call to our API (or CMS) in this component to get the content of the article.&lt;/p&gt;

&lt;p&gt;Also, we need to prepare a behavior on this page when the request does not found any result. Because, for example, if the user want to access the page &lt;em&gt;article/typeThatDoesNotExist/IdThatDoesNotExist&lt;/em&gt;, then he will “&lt;strong&gt;&lt;em&gt;fall&lt;/em&gt;&lt;/strong&gt;” on our fallback page.&lt;/p&gt;

&lt;p&gt;We can then either choose to redirect it to the 404 page (with a &lt;code&gt;navigate(&lt;/code&gt;/404&lt;code&gt;, { replace: true })&lt;/code&gt;), or display an error such as “Unfortunately this article does not exist”.&lt;/p&gt;

&lt;p&gt;Feel free to ask your question in the comments, I will answer it with pleasure.&lt;/p&gt;

</description>
      <category>gatsby</category>
      <category>react</category>
      <category>routes</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Page 404 multilingue - Gatsby.js</title>
      <dc:creator>Adrian Guery</dc:creator>
      <pubDate>Fri, 21 Jan 2022 08:36:40 +0000</pubDate>
      <link>https://dev.to/kezios/page-404-multilingue-gatsbyjs-51g9</link>
      <guid>https://dev.to/kezios/page-404-multilingue-gatsbyjs-51g9</guid>
      <description>&lt;p&gt;Aujourd'hui, nous allons voir comment, en Gatsby.js, nous pouvons faire en sorte d'avoir une page 404 par langue. Par exemple, si nous cherchons à accéder à l'url : &lt;em&gt;{votresite}.com/en/page-qui-nexiste-pas&lt;/em&gt;, le serveur renverra une page 404 différente de celle qu'il nous retournera si nous cherchons à accéder à l'url :&lt;br&gt;
&lt;em&gt;{votresite}.com/fr/page-qui-nexiste-pas&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Introduction :
&lt;/h2&gt;

&lt;p&gt;En Gatsby.js il est très simple de mettre en place une page 404 pour l'intégralité du site. Pour cela, il nous suffit de créer une page &lt;em&gt;404.jsx/tsx&lt;/em&gt; (souvent déjà générée dans les templates) dans le dossier &lt;strong&gt;&lt;em&gt;pages&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Mais dans ce cas, cette page sera la même pour toutes les langues. Nous nous souhaitons avoir une page spécifique par langue.&lt;/p&gt;
&lt;h2&gt;
  
  
  Les solutions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Approche 1 : Créer une page 404 par langue et faire une redirection&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Une première approche (pas la meilleure), est de créer une page 404 par langue dans le dossier pages. &lt;/p&gt;

&lt;p&gt;Par exemple : &lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjyhu0zgrf152s8an1rs9.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%2Fjyhu0zgrf152s8an1rs9.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nous pouvons alors réaliser une redirection vers cette page, dans la page 404.jsx, en fonction de la langue de l'utilisateur, grâce à ce code :&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="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="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;navigate&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="s2"&gt;gatsby&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getRedirectLanguage&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;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nb"&gt;navigator&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="s2"&gt;`undefined`&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fr&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;languages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;languages&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;language&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="nx"&gt;languages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;languages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="na"&gt;lang&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&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;lang&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;languages&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fr&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;actualLanguage&lt;/span&gt;
  &lt;span class="nx"&gt;languages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lang&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;lang&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fr&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;actualLanguage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fr&lt;/span&gt;&lt;span class="dl"&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;lang&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;en&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;actualLanguage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;en&lt;/span&gt;&lt;span class="dl"&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;lang&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;de&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;actualLanguage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;de&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;actualLanguage&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fr&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;NotFoundPage&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="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;urlLang&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getRedirectLanguage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="nf"&gt;navigate&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;urlLang&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="na"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&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;NotFoundPage&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Le problème est que l'utilisateur est redirigé, mais surtout il perd son url. Ce n'est pas un comportement souhaitable pour une page 404.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Approche 2 : Utiliser le _&lt;/strong&gt;matchPath*&lt;em&gt;_ API de Gatsby.js&lt;/em&gt;*&lt;/p&gt;

&lt;p&gt;La bonne approche est d'utiliser le paramètre &lt;em&gt;matchPath&lt;/em&gt; de Gatsby.js. En reprenant la création d'une page 404 par langue dans le dossier pages et grâce à l'API &lt;em&gt;onCreatePage&lt;/em&gt; de Gatsby, nous pouvons, lors de leur création, modifier le &lt;em&gt;matchPath&lt;/em&gt; des pages 404.&lt;/p&gt;

&lt;p&gt;Et si c'est une page 404, il nous suffit de changer son &lt;em&gt;matchPath&lt;/em&gt; par &lt;code&gt;/${langCode}/*&lt;/code&gt;.&lt;br&gt;
Ainsi, cette page sera affichée à chaque fois que le client cherche à accéder à une URL de la langue, sauf bien sûr pour les pages existantes.&lt;/p&gt;

&lt;p&gt;Voici le code nécessaire pour réaliser cette modification de &lt;em&gt;matchPath&lt;/em&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="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onCreatePage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;actions&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createPage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;deletePage&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;actions&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/^&lt;/span&gt;&lt;span class="se"&gt;\/[&lt;/span&gt;&lt;span class="sr"&gt;a-z&lt;/span&gt;&lt;span class="se"&gt;]{2}\/&lt;/span&gt;&lt;span class="sr"&gt;404&lt;/span&gt;&lt;span class="se"&gt;\/&lt;/span&gt;&lt;span class="sr"&gt;$/&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;oldPage&lt;/span&gt; &lt;span class="o"&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;page&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;language&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&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="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;matchPath&lt;/span&gt; &lt;span class="o"&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;language&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/*`&lt;/span&gt;

    &lt;span class="nf"&gt;deletePage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;oldPage&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;createPage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="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;Ce code modifiera donc le &lt;em&gt;&lt;strong&gt;matchPath&lt;/strong&gt;&lt;/em&gt; de toutes les pages 404 dans toutes les langues, par exemple : /fr/404, /de/404, etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;Nous avons ainsi réussi à mettre en place une page 404 différente par langue grâce à l'API &lt;em&gt;&lt;strong&gt;onCreatePage&lt;/strong&gt;&lt;/em&gt; de Gatsby.js.&lt;/p&gt;

&lt;p&gt;Cela nous permet maintenant de créer une page 404 spécifique par langue, tout en gardant l'URL erroné.&lt;/p&gt;

&lt;h2&gt;
  
  
  Source
&lt;/h2&gt;

&lt;p&gt;Si vous le souhaitez, vous pouvez retrouver la documentation de Gatsby.js sur ce sujet ici :&lt;br&gt;
&lt;a href="https://www.gatsbyjs.com/docs/creating-prefixed-404-pages-for-different-languages/" rel="noopener noreferrer"&gt;https://www.gatsbyjs.com/docs/creating-prefixed-404-pages-for-different-languages/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>gatsby</category>
      <category>intl</category>
      <category>404</category>
      <category>seo</category>
    </item>
  </channel>
</rss>
