<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Daniel Adetola</title>
    <description>The latest articles on Forem by Daniel Adetola (@adedaniel).</description>
    <link>https://forem.com/adedaniel</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%2F398847%2F3938f1e1-9c48-4cdb-8b0d-5ab05d2ebe81.jpeg</url>
      <title>Forem: Daniel Adetola</title>
      <link>https://forem.com/adedaniel</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/adedaniel"/>
    <language>en</language>
    <item>
      <title>Google like a PRO! - A guide to productive Googling</title>
      <dc:creator>Daniel Adetola</dc:creator>
      <pubDate>Wed, 21 Feb 2024 09:38:27 +0000</pubDate>
      <link>https://forem.com/adedaniel/google-like-a-pro-a-guide-to-productive-googling-2daf</link>
      <guid>https://forem.com/adedaniel/google-like-a-pro-a-guide-to-productive-googling-2daf</guid>
      <description>&lt;p&gt;Someone once said, &lt;em&gt;"The secret to getting anything is to ask properly"&lt;/em&gt;. You either ask, bargain, or convince. Either way, you are simply making a request with the right parameters.&lt;/p&gt;

&lt;p&gt;The Google search engine may not be a person, but we definitely need to ask questions to get results, so we need to ask properly.&lt;/p&gt;

&lt;p&gt;In this article, we will delve into how Google works and how to get the exact answers you need from Google, every time (or at least, almost every time).&lt;/p&gt;

&lt;p&gt;Let’s assume I wake up one morning and decide that I want to get fit. Well, then I need to start doing exercise. I need workouts. I need regular routines. So I’ll just check Google for some.&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%2Fmedia4.giphy.com%2Fmedia%2Fv1.Y2lkPTc5MGI3NjExOGVoaDRwOGN5MnM4M2RoZm9yc3FvbTg3NmFvdGxzaHZsOTZkaWNhMSZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw%2F3orieV5EDBgp2e2GmQ%2Fgiphy.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%2Fmedia4.giphy.com%2Fmedia%2Fv1.Y2lkPTc5MGI3NjExOGVoaDRwOGN5MnM4M2RoZm9yc3FvbTg3NmFvdGxzaHZsOTZkaWNhMSZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw%2F3orieV5EDBgp2e2GmQ%2Fgiphy.gif" alt="Homer simpson grunting"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If I go to Google and search “regular gym exercises,"  I get something like this:&lt;/p&gt;

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

&lt;p&gt;Not exactly what I want, eh? However, if I enter “gym workout routines",  here's what I get:&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%2Ffpwrhep3wdzy0s1jmvmx.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%2Ffpwrhep3wdzy0s1jmvmx.png" alt="gym workout routines search"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That looks more like it!&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%2Fi.giphy.com%2F3orieZOr8fdbGbNmTK.webp" 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%2Fi.giphy.com%2F3orieZOr8fdbGbNmTK.webp" alt="That looks more like it"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's take another example. Some days ago I was wondering how the right amount of water always managed to remain at the bottom of a toilet bowl no matter how many times you flushed it. So the first time I asked Google, I asked &lt;em&gt;“Why does the water in the toilet not drain away”&lt;/em&gt;. Here’s what I got:&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%2Fbqfi5g0ufoow62hmhm40.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%2Fbqfi5g0ufoow62hmhm40.png" alt="Why does the water in the toilet not drain away search"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Apparently, Google thought I was trying to fix a faulty toilet. which was definitely not what I intended. So I decided to rephrase the question and give it another shot. This time around, I typed in “How does the the toilet bowl hold water”. Here’s what I got this time around:&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%2F2v8d70tsd775qflmx552.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%2F2v8d70tsd775qflmx552.png" alt="How does the the toilet bowl hold water search"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that explains it!&lt;/p&gt;

&lt;p&gt;Now this begs the question - How do I get Google to give me the answers I want?&lt;br&gt;
To answer that question, we need to first understand how Google works.&lt;/p&gt;

&lt;p&gt;When you type a question into the Google search bar, here’s what happens:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Google's algorithms analyze the query (question) to understand its meaning, intent, and context. This involves breaking down the query into its constituent parts, such as keywords, phrases, and syntactic structures, using Natural Language Processing (NLP) to decipher the semantics, syntax, and context of the query and better understand the user's intent&lt;/li&gt;
&lt;li&gt;Google's algorithms then go through the vast index of web pages and other online content that the search engine has crawled and then use hundreds of factors to determine the relevance of these web pages to a given query. These factors include the presence of keywords, the quality of content, user engagement metrics, and the authority of the website.&lt;/li&gt;
&lt;li&gt;Finally, Google provides you with the answers or websites that closely match your query and are most likely to contain answers to your questions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now that you have this knowledge, let's look at ways to make sure you get the exact answers you want anytime you type into the search bar!&lt;/p&gt;

&lt;h2&gt;
  
  
  Tips for Getting Precise Answers from Google
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Google is not a person:&lt;/strong&gt;&lt;br&gt;
Sometimes, we tend to have the common misconception that Google thinks like a human, probably because it can answer how, when, where, and who questions in our natural language. This is wrong. Google is just a set of algorithms, so all the “why”s, “where”s, and “who”s are mostly filtered out except for cases where they are very necessary parts of the question.&lt;/p&gt;

&lt;p&gt;For example, “What is Obama's age”, or “How old is Obama”, can be simply reduced to “Obama age”. This is shorter and makes it easier for the search engine to pick out the keywords "Obama" and "age."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. When querying Google, don't be an asker; be a commander:&lt;/strong&gt;&lt;br&gt;
While this does not apply to all questions and inquiries, this method still works pretty well. Don't go begging Google for information, because if you do, you might end up with vague and irrelevant information.&lt;/p&gt;

&lt;p&gt;Take yourself as an interrogator and let Google be your suspect. As an interrogator, you don't ask, "Can you tell me?" rather, you say, "Tell me." Instead of “Is there a way for me to do xyz”, just say “How to do xyz”. The more direct the question, the better.&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%2Fmedia2.giphy.com%2Fmedia%2Fv1.Y2lkPTc5MGI3NjExMHkzcXZibnhuc2NzbGQ3NnY1eTYwOHVrZm9kOWRzamR2bnRtamt6cCZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw%2FyZOZWK6vE8V8YwZ6ws%2Fgiphy.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%2Fmedia2.giphy.com%2Fmedia%2Fv1.Y2lkPTc5MGI3NjExMHkzcXZibnhuc2NzbGQ3NnY1eTYwOHVrZm9kOWRzamR2bnRtamt6cCZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw%2FyZOZWK6vE8V8YwZ6ws%2Fgiphy.gif" alt="Give me GIF"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Use fewer, exact keywords:&lt;/strong&gt;&lt;br&gt;
Always remember that Google looks for keywords to identify your question topic and bring results, so you would want to use direct and specific keywords so that the search engine understands perfectly what you need to know.&lt;/p&gt;

&lt;p&gt;This is also another reason we should always try to make our queries as short as possible - so that the chances of Google picking up unnecessary keywords are significantly reduced.&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%2Fi.giphy.com%2Fhr4a3zHDK6ipW9o71a.webp" 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%2Fi.giphy.com%2Fhr4a3zHDK6ipW9o71a.webp" alt="Less is more GIF"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Ask yourself before asking Google:&lt;/strong&gt;&lt;br&gt;
Chances are, you might figure out the solution before even typing out the question if you do this. When confused and stuck, sit back and vocalize what you are trying to solve. A teammate told me it is called Rubber Duck Debugging (or Rubberducking). Pretend you're explaining the issue to someone who doesn't understand coding (or whatever line of profession your issue is coming from).&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%2Fim2agcg6hh8ufo00evpx.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%2Fim2agcg6hh8ufo00evpx.png" alt="Rubber duck GIF"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The problem is that we often think too much in one particular direction and fail to think that the problem question can be rephrased to give better search results.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Avoid the XY questions&lt;/strong&gt;&lt;br&gt;
The XY questions arise from XY problems. The XY problem is a communication problem where the question is about an end user's attempted solution (X) rather than the root problem itself (Y or Why?). It usually happens like this&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User wants to do X.&lt;/li&gt;
&lt;li&gt;User doesn't know how to do X, but thinks they can fumble their way to a solution if they can just manage to do Y.&lt;/li&gt;
&lt;li&gt;User doesn't know how to do Y either.&lt;/li&gt;
&lt;li&gt;User asks for help with Y.&lt;/li&gt;
&lt;li&gt;Others (or Google) try to help user with Y, but are confused because Y seems like a strange problem to want to solve.&lt;/li&gt;
&lt;li&gt;After much interaction and wasted time, it finally becomes clear that the user really wants help with X, and that Y wasn't even a suitable solution for X.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So to avoid this time-wasting process, make sure you know the very root cause of what you're trying to fix and what exactly you're trying to achieve. By doing this, we don't keep going in circles and have Google looking like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.giphy.com%2F3oKHWj284gLQoLTjFe.webp" 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%2Fi.giphy.com%2F3oKHWj284gLQoLTjFe.webp" alt="What exactly do you want GIF"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To help us further, Here are some types of questions we normally want to ask, and these are how they can be rephrased to give Google a better context of what your intent is.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1) Process questions:&lt;/strong&gt; When you want to know how to do something or how something is done, you should mostly Begin with&lt;/p&gt;

&lt;p&gt;How to (perform tasks)&lt;/p&gt;

&lt;p&gt;Ways to (perform task)&lt;/p&gt;

&lt;p&gt;Eg. “How to set up Android Studio on Mac”&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2) Understanding questions:&lt;/strong&gt; When you want to know how or why something exists or why one should take a particular action or decision, you mostly want to start your question with “why” or “what”.&lt;/p&gt;

&lt;p&gt;For example, "Why use a Js framework?", “Why do I have a brain?”, “what makes the ocean blue?”&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3) Comparison questions:&lt;/strong&gt; To know the better of two or more options or the difference between them. In this case most times, use “vs”).&lt;/p&gt;

&lt;p&gt;For example, “PHP vs JS”&lt;/p&gt;

&lt;p&gt;“React vs Angular”&lt;/p&gt;

&lt;p&gt;“Core i5 vs Core i7”&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4) Explanation questions:&lt;/strong&gt; To get full details about a particular topic.&lt;/p&gt;

&lt;p&gt;For example, “All about programming”, “Explain SAAS”, etc&lt;/p&gt;

&lt;p&gt;In conclusion, these methods do not apply to every situation, there are also a few cases where it is necessary to use questions and long texts to explain the situation. However, the purpose of this article is to help software developers quickly fix bugs or coding issues, which would usually take a lot of time, energy, and probably coffee too.&lt;/p&gt;

&lt;p&gt;I hope this article has helped you gain insights into how Google works and how to make the best use of it when asking questions.&lt;/p&gt;

&lt;p&gt;Till I come your way again!&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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1596277672751%2FTzsRc-1ax.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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1596277672751%2FTzsRc-1ax.gif" alt="Thats all folks"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>google</category>
      <category>productivity</category>
      <category>webdev</category>
      <category>help</category>
    </item>
    <item>
      <title>Dealing with Legacy Code as an Engineer</title>
      <dc:creator>Daniel Adetola</dc:creator>
      <pubDate>Fri, 02 Feb 2024 22:30:51 +0000</pubDate>
      <link>https://forem.com/adedaniel/dealing-with-legacy-code-as-an-engineer-261d</link>
      <guid>https://forem.com/adedaniel/dealing-with-legacy-code-as-an-engineer-261d</guid>
      <description>&lt;p&gt;Joining a new development team or company can be really exciting, but what happens when you discover that the codebase you're inheriting is built on ancient frameworks and practices?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Don't fret!&lt;/strong&gt; This article is your guide to navigating the challenges of working with legacy codebases, ensuring you can maintain, innovate and build on them without disrupting the delicate balance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Leverage Version Control - Git
&lt;/h2&gt;

&lt;p&gt;Protecting the codebase against unintentional mishaps is crucial. If one is not already in place, go with a stable version control system like Git. To effectively manage collaborative development and track changes, use Git. Make sure every modification has a complete record. Make use of insightful commit messages to make the goal and effects of each change clear.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Establish a well-defined branching plan to efficiently oversee feature creation, bug fixes, and releases. Provide instructions on how to create branches for experimenting with legacy code.&lt;/li&gt;
&lt;li&gt;Mark important releases or milestones using the Tag feature in the version control system. It's an easy way to quickly find important points in the codebase's evolution.&lt;/li&gt;
&lt;li&gt;Create dedicated branches for legacy code experimentation. Hence, You can ensure that your bold coding explorations won't disturb the tranquillity of the main codebase while you test and conveniently break some stuff 😂.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By implementing these best practices, you not only safeguard your codebase but also establish a disciplined and orderly setting for cooperative coding projects. When it comes to tracking changes, guaranteeing traceability, and encouraging a productive development process, version control proves to be invaluable. Also, regular merges keep everything harmonious. 👌🏽&lt;/p&gt;

&lt;h2&gt;
  
  
  Refactor with Caution
&lt;/h2&gt;

&lt;p&gt;Refactoring is great, if you do it right. Use it to tidy up your code, making it more readable and maintainable. The key here is gradual change—small tweaks, followed by thorough testing. Rinse and repeat. This way, you can bring the codebase into the present without compromising its stability. When refactoring, make sure to test everything thoroughly and concentrate on small, gradual changes. To properly navigate this process, here are things you can do:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Build an extensive test suite that addresses edge cases, critical paths, and frequently used features.&lt;/li&gt;
&lt;li&gt;Incorporate automated testing tools to help with regression testing and quickly find possible problems.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Integrate Contemporary Elements
&lt;/h2&gt;

&lt;p&gt;The secret to a successful code modernization process is to strategically isolate outmoded components within your code. This entails a thorough analysis of the current codebase to determine which parts require updating. After being located, these antiquated parts are methodically swapped out for modern equivalents to make sure they work and integrate with the current codebase. It's like giving your code a makeover!💅 - a revitalization that keeps the essential functionality intact while slickly integrating contemporary components. The objective is to improve the codebase's overall efficiency and adaptability while adding shiny new features. Throughout this modernization, it is critical to remain careful to preserve the core functionality of the code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Again&lt;/strong&gt;, rigorous testing is required here in order to ensure that the incorporation of modern elements does not jeopardize the essence/functionality of the code, ensuring both innovation and reliability in the end.&lt;/p&gt;

&lt;h2&gt;
  
  
  Write Documentation
&lt;/h2&gt;

&lt;p&gt;In the realm of legacy code, documentation is your beacon. Keep your documentation up to date in order to reduce the learning curve for others, and safeguard against potential errors. To accomplish this, consider the following practices:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use comments in your code to explain complex logic or business rules. These comments serve as guideposts, helping developers navigate through complex code sections.&lt;/li&gt;
&lt;li&gt;APIs and interfaces should be thoroughly documented to improve integration and understanding. Documentation here serves as a manual, clarifying the interactions between various system components.&lt;/li&gt;
&lt;li&gt;Provide a high-level overview of the system's architecture and explain key design decisions. Here, it serves as a map, guiding developers through the codebase's overall structure. This could be in a README file or something similar.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By incorporating these documentation practices, you not only ease the comprehension of your teammates but also strengthen the codebase against the potential pitfalls of ambiguity, resulting in a more resilient and collaborative development process.&lt;/p&gt;

&lt;h2&gt;
  
  
  Plan strategically for New Features
&lt;/h2&gt;

&lt;p&gt;Adding new features? Plan strategically, design the integration meticulously.&lt;/p&gt;

&lt;p&gt;When you start adding new features to your software, it is critical to take a strategic approach and meticulous design to ensure a smooth and seamless transition.&lt;/p&gt;

&lt;p&gt;Backward compatibility is a key principle to follow during this process. This means that new features should be introduced in a way that does not disrupt existing functionality. Consider it as adding a new thread to the intricate fabric of your current codebase. This includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Understanding the nuances of the existing system,&lt;/li&gt;
&lt;li&gt;Identifying potential points of impact, and&lt;/li&gt;
&lt;li&gt;Ensuring that the introduction of new elements does not jeopardize the stability of what is already in place.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This detailed and careful approach to planning and integration contributes to a harmonious blend of innovation within the existing code. It is not just about adding new features; it is about improving the system's capabilities while maintaining the reliability and integrity of the existing structure.&lt;/p&gt;

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

&lt;p&gt;Maintaining and building on legacy code isn't just a challenge; it's an opportunity for innovation. Whether we like it or not, there's always going to be legacy code. Even the modern frameworks and patterns we use today are going to be considered in a couple of years - as old, legacy code. Thus, by strategically approaching the complexities, you can transform your legacy code into a robust foundation for future development. Happy Hacking!&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>javascript</category>
      <category>performance</category>
      <category>coding</category>
    </item>
    <item>
      <title>Top 6 VSCode extensions for every Frontend Engineer</title>
      <dc:creator>Daniel Adetola</dc:creator>
      <pubDate>Mon, 22 Jan 2024 13:02:55 +0000</pubDate>
      <link>https://forem.com/adedaniel/top-6-vscode-extensions-for-every-frontend-engineer-55kp</link>
      <guid>https://forem.com/adedaniel/top-6-vscode-extensions-for-every-frontend-engineer-55kp</guid>
      <description>&lt;p&gt;&lt;strong&gt;Visual Studio Code&lt;/strong&gt; (commonly known as &lt;strong&gt;VSCode&lt;/strong&gt;) is unarguably one of the best IDEs for development. On top of that, It has so many extensions that can help speed up your work and give you a satisfying developer experience.&lt;/p&gt;

&lt;p&gt;Here are the top 5 VSCode extensions that I use for my day-to-day frontend engineering:&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://marketplace.visualstudio.com/items?itemName=dsznajder.es7-react-js-snippets"&gt;ES7+ React/Redux/React-Native snippets&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;ES7+ snippets are like magic for developers. They are short, reusable code snippets created to make repeated coding declarations and statements easier in React, Redux, and React-Native.&lt;br&gt;
For Javascript or React newbies, these snippets minimize the need to always retype basic Javascript code. They improve speed and consistency, but knowing the code is also very essential. Embrace these conveniences, personalize them, and transform your programming experience.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foulgazqgpttchfaywhoe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foulgazqgpttchfaywhoe.png" alt="IES7+ React/Redux/React-Native snippets" width="800" height="432"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://marketplace.visualstudio.com/items?itemName=GitHub.copilot"&gt;GitHub Copilot&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;GitHub Copilot transforms your coding experience by offering real-time AI ideas within your Integrated Development Environment (IDE). Whether you're starting to write code or explaining it in natural language, Copilot offers autocomplete-style ideas from an AI pair coder.&lt;br&gt;
GitHub Copilot follows responsible standards, which ensure that your code samples are private and are not used as suggestions for other users.&lt;/p&gt;

&lt;p&gt;GitHub Copilot makes use of OpenAI, which provides real-time coding assistance derived from billions of lines of open-source code.&lt;br&gt;
Copilot supports any language, such as Java, PHP, Python, JavaScript, Ruby, Go, C#, or C++. It's also integrated into your editor and works quickly and effectively as you type.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  &lt;a href="https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode"&gt;Prettier - Code formatter&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Maintaining consistent and visually appealing code in the coding world may be difficult many times. Prettier, your trusty code formatter, can help here. Prettier is a powerful tool that simplifies formatting, ensuring that your code is not only functional but also visually appealing.&lt;br&gt;
Prettier examines your code and formats it according to established standards. Prettier supports a wide range of languages, including JavaScript, TypeScript, HTML, CSS, and more. It parses and rewrites your code in a consistent and visually pleasing manner.&lt;/p&gt;

&lt;p&gt;In the ever-changing world of software development, Prettier is a shining example of simplicity and beauty. Prettier is your code formatting go-to, adding harmony and elegance to your work.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  &lt;a href="https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer"&gt;Live Server&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Beginning web development frequently entails a loop of writing code, saving files, and then refreshing the browser to view changes. Enter Live Server, a game-changing solution that helps to speed this procedure. Live Server spins up a local development server that instantly updates your web page anytime you make changes, resulting in a dynamic and efficient development experience.&lt;/p&gt;

&lt;p&gt;In the fast-paced world of web development, Live Server emerges as an invaluable tool, providing real-time updates to changes in your code changes instantly. Embrace Live Server's efficiency and simplicity to speed up your online development journey.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  &lt;a href="https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-docker"&gt;Docker&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Docker is a groundbreaking technology in software development, altering how programs are produced, deployed, and run. Docker allows developers to construct and deploy programs in lightweight, portable containers, assuring consistency and efficiency across several settings.&lt;/p&gt;

&lt;p&gt;Docker has quickly become an essential tool in modern software development, allowing developers to create, ship, and execute programs effectively. Add Docker to your VSCode toolkit and benefit from the agility and consistency it delivers to your development workflow.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  &lt;a href="https://marketplace.visualstudio.com/items?itemName=christian-kohler.path-intellisense"&gt;Path Intellisense&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Navigating file paths in a project can be time-consuming, but Path Intellisense makes the process easier. Path Intellisense is a VS Code addon that improves the coding experience by generating intelligent suggestions for file paths, making file referencing and inclusion easier.&lt;/p&gt;

&lt;p&gt;Path Intellisense streamlines file path navigation, ensuring that files are referenced correctly and efficiently inside your applications.&lt;/p&gt;

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

&lt;p&gt;In conclusion, We've seen how each tool helps to navigate and speed up the various areas of the development process. With these extensions at your disposal, you'll be a lot more productive and have a superb development experience. Leverage the power of these VSCode extensions, customize them to your taste and watch your productivity skyrocket. &lt;/p&gt;

&lt;p&gt;Happy hacking!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SpH8VGrt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1596277672751/TzsRc-1ax.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SpH8VGrt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1596277672751/TzsRc-1ax.gif" alt="Thats all folks" width="499" height="366"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>vscode</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Leveraging the Loading UI in Next.js App Router</title>
      <dc:creator>Daniel Adetola</dc:creator>
      <pubDate>Tue, 16 Jan 2024 03:21:21 +0000</pubDate>
      <link>https://forem.com/adedaniel/leveraging-the-loading-ui-in-nextjs-app-router-3bd6</link>
      <guid>https://forem.com/adedaniel/leveraging-the-loading-ui-in-nextjs-app-router-3bd6</guid>
      <description>&lt;p&gt;Lately, I've been diving deep into the new feature releases that came with Next.js 13 and 14. The latest version - Next 14, was released on the 26th of October 2023 and came with a couple of new features such as Turbopack and Server Actions along with new features like the disruptive App router and new data fetching methods.&lt;/p&gt;

&lt;p&gt;Many of us old-time Next.js users probably haven’t started exploring the new Next.js features (or haven't started needing to). However, I’ve been quite intrigued by the new releases and what they claim to offer, and one of them is the &lt;strong&gt;Instant Loading State&lt;/strong&gt; feature that enables you to pre-render a loading UI in a particular section of the page where data is still being fetched inside the server.&lt;/p&gt;

&lt;p&gt;In case the last sentence sounds like gibberish, let me give an example; Let's say we have a blog post page that is being server-side-rendered. The page has a &lt;code&gt;Navbar&lt;/code&gt;, &lt;code&gt;Menubar&lt;/code&gt;, &lt;code&gt;Footer&lt;/code&gt;, The &lt;code&gt;PostDetails&lt;/code&gt; and finally, the &lt;code&gt;Comments&lt;/code&gt; section.&lt;/p&gt;

&lt;p&gt;Now there are two things we would want to achieve:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;We want to fetch the comments data during the server-side rendering, but,&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We don't want to delay the display of other static pages like the &lt;code&gt;Navbar&lt;/code&gt;, &lt;code&gt;Menubar&lt;/code&gt;, &lt;code&gt;Footer&lt;/code&gt; and the &lt;code&gt;PostDetails&lt;/code&gt; while waiting for the data in the Comments component to get fetched.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So what does Next.js do in this case? It temporarily replaces that comments component with a fallback UI to be shown in the browser while fetching the data needed for the comments section in the background (server). This concept probably already reminds you of something similar... yes you're right, the &lt;strong&gt;React Suspense!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In fact, the only difference is that Next.js' Loading state runs its suspense on the server, as opposed to the basic React Suspense which we usually only run on the client side.&lt;/p&gt;

&lt;p&gt;So in our server, we have something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8wit9dfnf1e79pdkta7m.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%2F8wit9dfnf1e79pdkta7m.png" alt="Code snippet of React Suspense in the server"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The backbone mechanism behind this ability is something known as &lt;strong&gt;&lt;em&gt;Streaming&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;When you hear Streaming, you probably instantly think of YouTube or Netflix. Well, it’s not exactly that, but I promise it’s a little bit close!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Streaming&lt;/strong&gt; is the mechanism that bridges the gap between fetching data from the server and loading pages quickly from the server side.&lt;/p&gt;

&lt;p&gt;To explain this concept better, let's take a look at what happens under the hood during Client-side rendering (CSR) and Server-side rendering (SSR).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In Client-side rendering:&lt;/strong&gt; React sends the HTML, CSS and Javascript to the browser through a script tag, and then the browser builds out the page and hydrates the page with the javascript. Then, the page becomes interactive.&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%2Fhr9y2pb2bl5sycj15i81.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%2Fhr9y2pb2bl5sycj15i81.png" alt="Client side rendering flow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can see here that all the users see is a blank screen up until the entire page is loaded and it becomes interactive. Data fetching can only occur after this is complete.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In Server-side rendering:&lt;/strong&gt; React (or in our case, Next.js) generates and builds out (renders) the HTML and CSS into a page on the server, and then sends that page to the browser. Similar to CSR, Javascript is also sent along and hydrates the page and makes it interactive.&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%2Fs11g09mkzp6a014ux5xd.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%2Fs11g09mkzp6a014ux5xd.png" alt="Server side rendering flow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A key advantage of SSR over CSR is that it allows data fetching to be done on the server and sent along with the page, hence, reducing the number of API calls to be made on the client. However, the user still sees a blank screen up until the page is displayed, and even after it is displayed, it still needs to wait for it to be completely hydrated before it becomes interactive. The wait takes longer, in fact, if data fetching needs to be done before the page is displayed. So the bigger the number or size of API calls on the server, the longer it takes before the page becomes fully interactive.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Problem statement:&lt;/strong&gt; The user still sees a blank screen up until the page is displayed, and even after it is displayed, it still needs to wait for it to be completely hydrated before it becomes interactive.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So how do we solve this? What we need is a way to&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Keep hidden only the parts that aren't ready to be displayed (ie. that are still being fetched) or replace them with a fallback loading UI, and;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Show the parts of the page that are ready to be displayed and do not require extra data fetching, eg, the menubar, navbar, footer etc, and make them interactive.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is where the process of streaming comes in to save the day!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Streaming is the process where React uses its  component to isolate a “data-fetch required component” and allow other parts of the page to be loaded asynchronously/simultaneously and become interactive, and also, show a temporary loading interface while waiting for the “data-fetch required component” to finishing fetching data.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Take a look at this: Assuming we had our component structure like this:&lt;/p&gt;

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

&lt;p&gt;Let us imagine that the data fetching only occurs on the &lt;code&gt;Comments&lt;/code&gt; component.&lt;/p&gt;

&lt;p&gt;Pre-streaming, the interactivity of the entire page and all its components will be deferred until the data fetching (that happens only in that comment section) is completed.&lt;/p&gt;

&lt;p&gt;Here’s how Streaming suspends (pun intended, lol) that issue:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9a9lzuj458rsv9mhd7ge.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%2F9a9lzuj458rsv9mhd7ge.png" alt="Code snippet of component structure with streaming enabled"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By using &lt;code&gt;&amp;lt;Suspense/&amp;gt;&lt;/code&gt; with react, our page flow now looks like this:&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Sweet right?&lt;/strong&gt; Super optimized too! Now the user doesn't need to feel like they’re waiting for anything at all because we’ve told React that it shouldn’t block the rest of the page from streaming—and, as it turns out, from hydrating, too! This means we no longer have to wait for all the code to load to start hydrating. React can hydrate parts as they’re being loaded.&lt;/p&gt;

&lt;p&gt;Thanks to Selective Hydration and the advent of Server components, a heavy piece of JS doesn’t prevent the rest of the page from becoming interactive. So you can click around on the Menubar or the Navbar or footer while the comments are being fetched in the server.&lt;/p&gt;

&lt;p&gt;Here’s how the render flow looks before and after, as described by Next.js&lt;/p&gt;

&lt;p&gt;Before:&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%2Fxzprf31mqu5on8ns7tpn.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%2Fxzprf31mqu5on8ns7tpn.png" alt="Render flow before Streaming"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After:&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%2F3bv5hdtt97bbr7bp8pjk.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%2F3bv5hdtt97bbr7bp8pjk.png" alt="Render flow after Streaming"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Now to the fun part!&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;To take advantage of this powerful feature in your Next.js App Router, all you need to do is create a &lt;code&gt;loading.tsx&lt;/code&gt; (I'm using typescript, it can be .jsx in your case) at the same file level as your &lt;code&gt;page.tsx&lt;/code&gt; where the data fetching is going to happen, so something like this:&lt;/p&gt;

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

&lt;p&gt;You can see that the &lt;code&gt;page.tsx&lt;/code&gt; and the &lt;code&gt;loading.tsx&lt;/code&gt; in the &lt;code&gt;posts/[postId]&lt;/code&gt; folder are on the same level, this lets Next.js know to automatically use that loading component as a fallback UI in the case of any server-side data fetching in its corresponding &lt;code&gt;page.tsx&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For now, let's have a simple text that says "Loading..." in our &lt;code&gt;loading.tsx&lt;/code&gt; file:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Now let's fetch some data in our &lt;code&gt;[postId]/page.tsx&lt;/code&gt; so we can test if this loading component works;&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Easy as that! Now the &lt;code&gt;getCommentsData&lt;/code&gt; will get called on the server whenever a route like &lt;code&gt;posts/1&lt;/code&gt; or &lt;code&gt;posts/abc&lt;/code&gt; is visited, and you'll see the result of the &lt;code&gt;console.log(data)&lt;/code&gt; as an array of objects, each containing the name, id, text, and email of the comment.&lt;/p&gt;

&lt;p&gt;Next, let's map the comments data into a list on our page, so our complete &lt;code&gt;[postId]/page.tsx&lt;/code&gt; looks like this:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Now let's check this out on our browser! When we hit the &lt;code&gt;/posts/[postId]&lt;/code&gt; route (eg. say localhost:3000/posts/1), we should see something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1704982320667%2F81c2294a-4052-4ecd-9af2-255a4de524ec.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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1704982320667%2F81c2294a-4052-4ecd-9af2-255a4de524ec.gif" alt="Loading UI in action"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sweet! We now see that the rendering of the layout components (like the navbar in this example) is not delayed by the data fetching in the &lt;code&gt;Comments&lt;/code&gt; component. The navbar is rendered immediately and a fallback is provided for the fetching of the comments, and once the comments are fetched, they are displayed on the screen. Beautiful stuff 🚀&lt;/p&gt;

&lt;p&gt;&lt;em&gt;NB: You might not notice the loading UI for very long if you're on a good network speed - you might mostly just see a flash of the loading screen, but once you throttle to a slower network, you should be able to see it for longer&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We now understand the principle of Streaming in React and how to effectively leverage it in Next.js by creating Loading pages in our App Router to make our websites and web apps as quick and responsive as possible.&lt;/p&gt;

&lt;p&gt;And that's it! Till I come your way again guys, Happy Hacking!&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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1596277672751%2FTzsRc-1ax.gif%3Fauto%3Dformat%2Ccompress%26gif-q%3D60%26format%3Dwebm" 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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1596277672751%2FTzsRc-1ax.gif%3Fauto%3Dformat%2Ccompress%26gif-q%3D60%26format%3Dwebm" alt="Thats all folks"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Read More:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://react.dev/reference/react/Suspense#suspense" rel="noopener noreferrer"&gt;https://react.dev/reference/react/Suspense#suspense&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://github.com/reactwg/react-18/discussions/37" rel="noopener noreferrer"&gt;https://github.com/reactwg/react-18/discussions/37&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://nextjs.org/docs/app/building-your-application/routing/loading-ui-and-streaming#instant-loading-states" rel="noopener noreferrer"&gt;https://nextjs.org/docs/app/building-your-application/routing/loading-ui-and-streaming#instant-loading-states&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://github.com/reactwg/react-18/discussions/22" rel="noopener noreferrer"&gt;https://github.com/reactwg/react-18/discussions/22&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://nextjs.org/docs/app/building-your-application/routing/loading-ui-and-streaming" rel="noopener noreferrer"&gt;https://nextjs.org/docs/app/building-your-application/routing/loading-ui-and-streaming&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>react</category>
      <category>ux</category>
      <category>loading</category>
    </item>
    <item>
      <title>Setting up your CMS' with Gatsby - PART 1: Contentful</title>
      <dc:creator>Daniel Adetola</dc:creator>
      <pubDate>Thu, 02 Jun 2022 19:52:03 +0000</pubDate>
      <link>https://forem.com/adedaniel/setting-up-your-cms-with-gatsby-part-1-contentful-4o79</link>
      <guid>https://forem.com/adedaniel/setting-up-your-cms-with-gatsby-part-1-contentful-4o79</guid>
      <description>&lt;p&gt;&lt;strong&gt;Hi there!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this article (and some others to come), We're gonna be going through how to set up some of your popular CMS platforms directly with Gatsby. It's going to be more like a series, so this first episode is going to be on Contentful.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Let's Dive into it!!!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--geEb3JBP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rchxfr5v2xwwdsa3oqwo.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--geEb3JBP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rchxfr5v2xwwdsa3oqwo.gif" alt="Image description" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So whether you're a newbie in web dev, or you're a seasoned engineer, you've probably already heard about Content Management Systems (CMS). Names like Contentful, Sanity, Prismic, Strapi, Netlify ...and WordPress are names that easily come to mind when you hear about CMS'.&lt;br&gt;
At this point, you might probably be thinking, &lt;strong&gt;&lt;em&gt;WordPress&lt;/em&gt;&lt;/strong&gt;?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1_FwcPGN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/48sr4p9wt4ubp8u4ce25.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1_FwcPGN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/48sr4p9wt4ubp8u4ce25.gif" alt="Image description" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I know, I know, WordPress? Although it sounds much more different from the others, it's actually also a CMS. The difference between platforms like WordPress, Wix, etc., and others like Contentful or Netlify is that the latter are known as &lt;strong&gt;Headless&lt;/strong&gt; CMS. ie. they manage &lt;strong&gt;&lt;em&gt;only&lt;/em&gt;&lt;/strong&gt; the content strictly, while the former - Traditional CMS' handle the frontend along with the content it provides. You can read more about that &lt;a href="http://udig.com/digging-in/traditional-cms-vs-headless-cms"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that we know what our CMS is, what better framework to integrate it with than Gatsby?&lt;/p&gt;
&lt;h3&gt;
  
  
  Gatsby provides methods to easily fetch CMS content using their GraphQL API, and use the content to create pages during build time.
&lt;/h3&gt;

&lt;p&gt;It also handles SEO quite well, has great developer experience and it's powered by our favorite framework - React!&lt;/p&gt;
&lt;h2&gt;
  
  
  Getting started
&lt;/h2&gt;

&lt;p&gt;The first thing we need to do is to create a Contentful account. (duh!) Once we can access the dashboard, the next thing we do is to create a &lt;strong&gt;Content Model&lt;/strong&gt;. If you're just creating an account for the first time, you should see something like this:&lt;/p&gt;

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

&lt;p&gt;Now we can create the Content Model, which I'll call &lt;strong&gt;Blog Post&lt;/strong&gt;, and it's going to look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EHVu9Oc7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3xku9ilx0ghuealjm2kg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EHVu9Oc7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3xku9ilx0ghuealjm2kg.png" alt="Image description" width="618" height="473"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once this is set up, we can go ahead to create the &lt;strong&gt;Blog Post&lt;/strong&gt; content from the "Content" tab on the dashboard navbar. Now, cross over to Gatsby and set things up over there too.&lt;/p&gt;
&lt;h2&gt;
  
  
  Time to write some code!
&lt;/h2&gt;

&lt;p&gt;We can &lt;a href="https://www.gatsbyjs.com/docs/quick-start"&gt;easily get started&lt;/a&gt; with the gatsby project by running &lt;code&gt;npm init gatsby&lt;/code&gt; which will provide us with the basic structure we'll need to get our gatsby project up and running. It's okay if you already have your gatsby app, just skip that part and keep reading.&lt;/p&gt;

&lt;p&gt;Now that our gatsby project is ready to be worked on, we'll need to store important details from our contentful application that will enable us to link it to our gatsby app. We'll keep these as .env secrets.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8lrbknAR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jbkhr4to9wiib6fkr8cz.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8lrbknAR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jbkhr4to9wiib6fkr8cz.gif" alt="Image description" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What we're gonna do is to create a file named &lt;code&gt;.env.development&lt;/code&gt; and it's gonna look like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# .env.development
CONTENTFUL_SPACE_ID='xxxxxxxxxxxx'
CONTENTFUL_ACCESS_TOKEN='XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To get our &lt;code&gt;CONTENTFUL_SPACE_ID&lt;/code&gt; and &lt;code&gt;CONTENTFUL_ACCESS_TOKEN&lt;/code&gt;, we need to go to &lt;code&gt;Settings&lt;/code&gt; &amp;gt; &lt;code&gt;API Keys&lt;/code&gt; where you should see something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0bypKxy2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/02zynvmdkuv15t52gk0z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0bypKxy2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/02zynvmdkuv15t52gk0z.png" alt="Image description" width="800" height="369"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on the "Add API Key" button as shown on the top right of the screenshot above and scroll down a bit on the next page to see something like this:&lt;/p&gt;

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

&lt;p&gt;Copy the value of the Space ID as our &lt;code&gt;CONTENTFUL_SPACE_ID&lt;/code&gt; and the value of the Content Delivery API - access token as our &lt;code&gt;CONTENTFUL_ACCESS_TOKEN&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;NB: The values in the &lt;code&gt;.env.development&lt;/code&gt; should be kept secret, and so, should not be committed to Git,  so you would need to add the .env.development to your &lt;code&gt;.gitignore&lt;/code&gt; (if it's not already automatically added)&lt;/p&gt;

&lt;p&gt;That done? Let's go on to our &lt;code&gt;gatsby-config.js&lt;/code&gt; and set up contentful there. &lt;br&gt;
Basically, we should update the file to look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// gatsby-config.js&lt;/span&gt;
&lt;span class="nf"&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;dotenv&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="c1"&gt;// You might need to install dotenv&lt;/span&gt;
  &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`.env.&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NODE_ENV&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;contentfulConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;spaceId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;CONTENTFUL_SPACE_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;accessToken&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;CONTENTFUL_ACCESS_TOKEN&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;spaceId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;accessToken&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;contentfulConfig&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;spaceId&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;accessToken&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Contentful spaceId and the access token need to be provided.&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;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="na"&gt;siteMetadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`...`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`....`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;siteUrl&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;plugins&lt;/span&gt;&lt;span class="p"&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gatsby-source-contentful&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// You'll need to install this too&lt;/span&gt;
      &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;contentfulConfig&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="c1"&gt;//... other optional plugins&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;At this point, you've successfully been able to connect Contentful to your gatsby app. What we basically did was pass in the &lt;strong&gt;spaceId&lt;/strong&gt; and access token (that we stored in our .env file earlier) to the &lt;code&gt;gatsby-source-contentful&lt;/code&gt; plugin so that contentful can create graphQL schemas from our blog content and allow us to fetch them when we need it.&lt;/p&gt;

&lt;p&gt;Now let's try to fetch and list all our Blog Posts and render them on our &lt;code&gt;pages/index.js&lt;/code&gt; page.&lt;/p&gt;

&lt;p&gt;We can easily do something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/pages/index.js&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;graphql&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="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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Layout&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;components/Layout&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;SEO&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;components/SEO&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;IndexPage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="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;posts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;allContentfulBlogPost&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nodes&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Layout&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;SEO&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Home&lt;/span&gt;&lt;span class="dl"&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;div&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;posts&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="nx"&gt;post&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;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&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;h3&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;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h3&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;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;By&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;authorName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;on&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;hr&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="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="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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Layout&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

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

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pageQuery&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;graphql&lt;/span&gt;&lt;span class="s2"&gt;`
  query BlogIndexQuery {
    allContentfulBlogPost {
      nodes {
        id
        slug
        subtitle
        title
        description
        authorName
        captionText
        tags
        date(formatString: "DD MMMM YYYY")
        image {
          gatsbyImageData(layout: FULL_WIDTH, placeholder: BLURRED)
        }
        authorImage {
          gatsbyImageData(layout: FULL_WIDTH, placeholder: BLURRED)
        }
        body {
          raw
        }
      }
    }
  }
`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Awesome right? We can easily use graphql page query to fetch and list all the content we created in contentful.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--m5LDz2Wq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xbdif1v5t845vy2r5syf.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--m5LDz2Wq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xbdif1v5t845vy2r5syf.gif" alt="Image description" width="178" height="119"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But we're not done yet...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WrTebP0n--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ek1cf2ygwalwxay0ge3l.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WrTebP0n--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ek1cf2ygwalwxay0ge3l.gif" alt="Image description" width="400" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Almost though, The next thing we need to do now is to use our &lt;strong&gt;Blog Post&lt;/strong&gt; contents to create pages so we can view each post on its own single page using the &lt;strong&gt;slug&lt;/strong&gt; field. That's where the &lt;code&gt;gatsby-node.js&lt;/code&gt; file comes in handy.&lt;/p&gt;

&lt;p&gt;If you haven't created it yet, create a file named &lt;code&gt;gatsby-node.js&lt;/code&gt; and add this to it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//gatsby-node.js&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="nf"&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="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createPages&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;graphql&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="nx"&gt;reporter&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="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;actions&lt;/span&gt;

  &lt;span class="c1"&gt;// Define a template for blog post and tagPosts&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;blogPostPath&lt;/span&gt; &lt;span class="o"&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;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;./src/templates/blog-post.jsx&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="c1"&gt;// Fetch all contentful blog posts&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;graphql&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;`
      {
        allContentfulBlogPost {
          nodes {
            title
            slug
          }
        }
      }
    `&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;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;reporter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;panicOnBuild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="s2"&gt;`There was an error loading your Contentful posts`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;errors&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;allContentfulBlogPost&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nodes&lt;/span&gt;

  &lt;span class="c1"&gt;// Create blog posts pages&lt;/span&gt;
  &lt;span class="c1"&gt;// But only if there's at least one blog post found in Contentful&lt;/span&gt;
  &lt;span class="c1"&gt;// `context` is available in the template as a prop and as a variable in GraphQL&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;posts&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;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;posts&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;post&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&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;createPage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;path&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;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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="nx"&gt;blogPostPath&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="na"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Here, we're using the &lt;code&gt;createPages&lt;/code&gt; export to make a quick graphql call to fetch the contentful posts, each item in the array will contain the &lt;code&gt;title&lt;/code&gt; and unique &lt;code&gt;slug&lt;/code&gt; of the post (In this case, we're using the &lt;code&gt;slug&lt;/code&gt; as the unique identifier, you might decide to use the &lt;code&gt;id&lt;/code&gt; if you want). &lt;br&gt;
Once we get the response from graphQL, we use the &lt;code&gt;forEach&lt;/code&gt; method to loop through each post item and use it to create a page using the &lt;code&gt;createPage&lt;/code&gt; function. We're passing the &lt;code&gt;slug&lt;/code&gt; as a context parameter so we can use it to get the post we want to display with the &lt;code&gt;blogPostPath&lt;/code&gt; template component.&lt;/p&gt;

&lt;p&gt;But first, we need to create the post template component at "./src/templates/blog-post.jsx". This file is going to be used to fetch and display the specified blog post. It can look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/templates/blog-post.jsx&lt;/span&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;graphql&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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Layout&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;components/Layout&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;SEO&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;components/SEO&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;GatsbyImage&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-plugin-image&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;documentToReactComponents&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;@contentful/rich-text-react-renderer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;BlogPostTemplate&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;contentfulBlogPost&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Layout&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;SEO&lt;/span&gt;
        &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;image&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;image&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;url&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;h1&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;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/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="nx"&gt;caption&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;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;captionText&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;/caption&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;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;By&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;authorName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;on&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;GatsbyImage&lt;/span&gt;
          &lt;span class="nx"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;post image&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
          &lt;span class="nx"&gt;image&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;gatsbyImageData&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;div&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;documentToReactComponents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;raw&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;/div&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;hr&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="sr"&gt;/Layout&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pageQuery&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;graphql&lt;/span&gt;&lt;span class="s2"&gt;`
  query BlogPostBySlug(
    $slug: String!
  ) {
    contentfulBlogPost(slug: { eq: $slug }) {
      id
      slug
      subtitle
      title
      authorName
      description
      captionText
      tags
      date(formatString: "MMMM Do, YYYY")
      image {
        url
        gatsbyImageData(layout: FULL_WIDTH, placeholder: BLURRED)
      }
      authorImage {
        gatsbyImageData(layout: FULL_WIDTH, placeholder: BLURRED)
      }
      body {
        raw
        references {
          contentful_id
          url
          title
          width
          height
          description
        }
      }
    }
  }
`&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Here, we're querying our post by finding the post whose slug matches the slug that comes with the page's content. So if our URL looks like "&lt;a href="https://localhost:8000/what-is-up"&gt;https://localhost:8000/what-is-up&lt;/a&gt;", we are going to find the post whose slug is "what-is-up" and return the details of the post (or return a 404 if we can't find such a post).&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping it up
&lt;/h2&gt;

&lt;p&gt;We've been able to set up our contentful dashboard, connect it to gatsby, fetch and list all the content we created in contentful using the graphql schema that &lt;code&gt;gatsby-source-contentful&lt;/code&gt; provides, and we've also been able to create pages during build time from posts in contentful. I hope that you've picked up a thing or two and you can now confidently start using Contentful in your Gatsby applications.&lt;/p&gt;

&lt;p&gt;Note that I didn't go into the styling of the UI in order to keep this article streamlined to the purpose of integrating Contentful with Gatsby. However, In your app, you'd definitely want to make the site a bit more beautiful. &lt;/p&gt;

&lt;p&gt;Well, that's all for now. Drop a like or a reaction if you enjoyed this read. Feel free to let me know in the comments if you have any questions, observations, or suggestions.&lt;br&gt;
Also, watch out for subsequent articles where I'll be showing how we can integrate gatsby with other CMS platforms easily.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sYt2o_ec--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q9stq0634p8mf6bjzqh0.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sYt2o_ec--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q9stq0634p8mf6bjzqh0.gif" alt="Image description" width="499" height="366"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Till I come your way again, have fun, and happy hacking! 🚀&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
