<?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: nefejames</title>
    <description>The latest articles on Forem by nefejames (@nefejames).</description>
    <link>https://forem.com/nefejames</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%2F148625%2Fc93b3ae5-a15a-4bda-b208-a5798fb5b32a.jpg</url>
      <title>Forem: nefejames</title>
      <link>https://forem.com/nefejames</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/nefejames"/>
    <language>en</language>
    <item>
      <title>Troubleshoot faster with Appwrite Cloud's active developer community</title>
      <dc:creator>nefejames</dc:creator>
      <pubDate>Tue, 27 Jun 2023 19:34:33 +0000</pubDate>
      <link>https://forem.com/hackmamba/troubleshoot-faster-with-appwrite-clouds-active-developer-community-m4d</link>
      <guid>https://forem.com/hackmamba/troubleshoot-faster-with-appwrite-clouds-active-developer-community-m4d</guid>
      <description>&lt;p&gt;Developers face several obstacles when developing applications on the cloud. One way they can overcome these challenges is by joining a vibrant and helpful developer community. Developers can significantly improve the cloud development experience and receive support by engaging with such communities.&lt;/p&gt;

&lt;p&gt;In this article, we will discuss the common challenges cloud developers encounter and how Appwrite Cloud's active &lt;a href="https://appwrite.io/discord"&gt;developer community&lt;/a&gt; can help us troubleshoot faster and build robust applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Appwrite Cloud?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://appwrite.io/cloud/?utm_source=hackmamba&amp;amp;utm_medium=hackmamba-blog"&gt;Appwrite Cloud&lt;/a&gt; is a robust backend solution that simplifies the complexities of managing and scaling cloud infrastructure and allows developers to focus on other critical development needs. It was developed by Appwrite, an open-source end-to-end &lt;a href="https://appwrite.io/?utm_source=hackmamba&amp;amp;utm_medium=hackmamba-blog"&gt;backend platform&lt;/a&gt; for web, cloud, and mobile developers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Features of Appwrite Cloud
&lt;/h2&gt;

&lt;p&gt;Appwrite Cloud provides the following features to help make cloud development easier.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Serverless architecture for easy scaling&lt;/strong&gt; &lt;br&gt;
Appwrite Cloud's serverless architecture eliminates the need to manage servers or infrastructure when building applications. Instead, it handles the scaling, maintenance, and management of servers automatically. This allows us to focus on building and writing code while Appwrite Cloud takes care of scaling based on demands.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Built-in user authentication and authorization&lt;/strong&gt; &lt;br&gt;
Appwrite Cloud's built-in solution handles the complexities of setting up and managing user authentication and authorization for us. This allows us to manage user access and permissions easily. It also helps save time and effort as we won't need to integrate with another system for our security needs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Secure and scalable cloud storage&lt;/strong&gt; &lt;br&gt;
Appwrite Cloud provides secure and scalable cloud storage options, allowing us to store and manage large amounts of data without worrying about infrastructure limitations. We can easily scale the storage as needed, and it also offers robust security to help protect sensitive data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real-time databases&lt;/strong&gt; &lt;br&gt;
Real-time databases are another feature that Appwrite Cloud provides, and it allows us to build applications with live data update functionalities. This means that users can access up-to-date information in real time, and the database automatically syncs data across all connected devices. This feature is excellent for applications that require real-time collaboration or require users to have access to the latest information, like chat apps or forums.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introducing Appwrite's developer cloud community
&lt;/h2&gt;

&lt;p&gt;Appwrite recognizes the importance of a strong and active developer community. Appwrite's community not only fosters collaboration and idea exchange, but it also provides valuable resources and support to developers at every stage of their cloud development journey. We can &lt;a href="https://appwrite.io/discord"&gt;access Appwrite's cloud community on Discord&lt;/a&gt;. Joining the community gives us access to perks like real-time assistance from professionals, code samples, tutorials, learning materials, and information on the latest product updates and announcements. We can also visit &lt;a href="https://github.com/appwrite/appwrite"&gt;Appwrite's GitHub repository&lt;/a&gt; to collaborate and engage the community.&lt;/p&gt;

&lt;h2&gt;
  
  
  Benefits of leveraging Appwrite's cloud community
&lt;/h2&gt;

&lt;p&gt;These are some of the benefits we can enjoy by joining Appwrite's community.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Access to advice and best practices&lt;/strong&gt; &lt;br&gt;
The first step to overcoming challenges is getting advice from experienced developers who have encountered similar issues. Appwrite's developer community is brimming with skilled individuals who are happy to share their expertise, tips, and best practices.&lt;/p&gt;

&lt;p&gt;Engaging in discussions with fellow developers helps us find solutions faster and enables us to learn from their experiences.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Expert feedback and answers to questions&lt;/strong&gt; &lt;br&gt;
In Appwrite's proactive community, anyone can ask questions or request feedback on their code or architecture. Doing so allows other developers to check for potential issues or improvements we may have missed.&lt;/p&gt;

&lt;p&gt;Appwrite's community is known for its friendly, inclusive, and helpful atmosphere.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real-time problem solving&lt;/strong&gt; &lt;br&gt;
Appwrite's developer community offers real-time support that allows us to quickly receive the help we need to get our project back on track without unnecessary delays.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Collaborative learning and networking&lt;/strong&gt; &lt;br&gt;
Being a part of Appwrite's developer community allows us to learn from others and share our expertise. We can build our knowledge and improve our skills by participating in discussions, asking and answering questions, and sharing our experiences. Also, networking with fellow developers can lead to new career opportunities and connections.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A chance to contribute and make an impact&lt;/strong&gt; &lt;br&gt;
We can give back to the community by sharing our knowledge and insights. This helps solidify our understanding of Appwrite's platform and fosters a supportive environment where everyone can learn and grow together. Appwrite's developer community's strength lies in its members' collective expertise, and our contributions can make a significant difference.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Latest updates on Appwrite news and features&lt;/strong&gt; &lt;br&gt;
Being a part of Appwrite's community means we will always be in the loop on the latest news, updates, and features. This helps us stay ahead of the curve and ensures we maximize Appwrite's powerful tools and resources to build great applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Importance of developer communities in problem-solving
&lt;/h2&gt;

&lt;p&gt;Cloud development comes with its fair share of challenges. Developers are often busy managing complex infrastructures and ensuring high availability. Let's explore the importance of developer communities and how they help address these challenges and speed up the troubleshooting process.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Collaborative problem-solving&lt;/strong&gt; &lt;br&gt;
A diverse and active developer community means we are never alone when tackling a problem. We can easily collaborate with other developers who have experienced similar issues, share ideas, and brainstorm possible solutions. This collaborative approach to problem-solving can significantly reduce the time spent troubleshooting and help us get back on track quickly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Access to expertise&lt;/strong&gt; &lt;br&gt;
Developer communities are often overflowing with experts who have a wealth of knowledge and experience in various aspects of cloud development. These experts are often more than happy to lend a hand and share their insights with others. By tapping into their expertise, we can gain a deeper understanding of cloud technologies and best practices, which can help us troubleshoot issues more efficiently.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Continuous learning and growth&lt;/strong&gt; &lt;br&gt;
Being part of an active developer community encourages continuous learning and professional growth. Joining a community gives us access to valuable resources, like tutorials, webinars, and blog posts, that can help us stay up-to-date with the latest trends and best practices in cloud development.&lt;/p&gt;

&lt;h2&gt;
  
  
  Challenges Apwrite's cloud community can help us solve
&lt;/h2&gt;

&lt;p&gt;Developing applications for the cloud comes with its own set of challenges. Here are some challenges developers face and how Appwrite's community and resources help solve them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Security concerns&lt;/strong&gt; &lt;br&gt;
Security is a top priority for cloud development, and it comes with its own unique challenges. Joining a developer community can help us learn about best practices and get advice from experienced developers on securing our applications and implementing robust access control measures.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scalability issues&lt;/strong&gt; &lt;br&gt;
Ensuring our application can scale efficiently is crucial. A developer community can provide insights into common bottlenecks, share experiences, and recommend tools or strategies to improve scalability.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Performance optimization&lt;/strong&gt; &lt;br&gt;
Optimal application performance is vital for user satisfaction. We can learn how to identify performance bottlenecks and implement effective solutions by engaging with a developer community.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deployment and management&lt;/strong&gt; &lt;br&gt;
Deploying and managing cloud applications can be complex. A developer community can offer guidance on deployment strategies, configuration management, and automation tools to streamline these processes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cost optimization&lt;/strong&gt; &lt;br&gt;
Managing costs is a concern for any cloud developer. A developer community can provide recommendations on cost-effective architectures, share cost-saving tips, and help us make informed decisions about cloud services.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Staying up-to-date with technologies&lt;/strong&gt; &lt;br&gt;
Cloud development is constantly evolving. By being part of a developer community, we can stay informed about new tools and technologies and learn from the experiences of other developers.&lt;/p&gt;

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

&lt;p&gt;Becoming a part of Appwrite's developer community gives us access to a wealth of knowledge, support, and resources that can help improve our troubleshooting efficiency.&lt;/p&gt;

&lt;p&gt;Don't miss out on the opportunity to learn from experienced developers, collaborate, and contribute to the success of others. &lt;a href="https://appwrite.io/discord"&gt;Join the Appwrite developer community&lt;/a&gt; today to get started.&lt;/p&gt;

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

&lt;p&gt;Explore the following resources to learn more about Appwrite.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://appwrite.io/?utm_source=hackmamba&amp;amp;utm_medium=hackmamba-blog"&gt;Appwrite&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://appwrite.io/cloud?utm_source=hackmamba&amp;amp;utm_medium=hackmamba-blog"&gt;Appwrite Cloud&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://appwrite.io/docs?utm_source=hackmamba&amp;amp;utm_medium=hackmamba-blog"&gt;Appwrite Documentation&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>appwrite</category>
      <category>cloud</category>
      <category>webdev</category>
      <category>developercommunity</category>
    </item>
    <item>
      <title>How This BaaS Platform Is Pushing the Boundaries of Scalable Data Storage</title>
      <dc:creator>nefejames</dc:creator>
      <pubDate>Mon, 13 Mar 2023 13:07:20 +0000</pubDate>
      <link>https://forem.com/hackmamba/how-this-baas-platform-is-pushing-the-boundaries-of-scalable-data-storage-3m8l</link>
      <guid>https://forem.com/hackmamba/how-this-baas-platform-is-pushing-the-boundaries-of-scalable-data-storage-3m8l</guid>
      <description>&lt;p&gt;As your company grows, so does the amount of data you need to store and manage. In an era where businesses are expected to grow and expand quickly, working with a scalable data storage solution has never been more important.&lt;/p&gt;

&lt;p&gt;To help meet the ever-changing growth demands of your business, you need to select a cloud data storage provider that can grow with you and effectively meet your business requirements. Without scalability, you may experience performance issues and potentially lose customers. &lt;/p&gt;

&lt;p&gt;This article will cover scalability, its role in cloud computing, and why you need scalable data storage.&lt;/p&gt;

&lt;h2&gt;
  
  
  Meaning of Scalability
&lt;/h2&gt;

&lt;p&gt;In terms of cloud computing, &lt;a href="https://www.section.io/blog/scaling-horizontally-vs-vertically/"&gt;Scalability&lt;/a&gt; refers to the ability to reduce or increase the number of computing resources in response to changes in demand. Scaling is one of the benefits of working with the cloud as it allows companies to manage their resources better and avoid waste. &lt;/p&gt;

&lt;p&gt;With cloud scalability, you can quickly scale your business operations without making significant upfront investments in hardware and other infrastructure. Implementing cloud scalability enables your resources to grow or reduce cost-effectively and in tandem with your traffic. Scalability protects you from future downtime and ensures the quality of your product.&lt;/p&gt;

&lt;h2&gt;
  
  
  Types of Scalability in Cloud Computing
&lt;/h2&gt;

&lt;p&gt;There are three types of scalability in cloud computing, and they are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://phoenixnap.com/glossary/vertical-scaling"&gt;Vertical Scaling&lt;/a&gt;&lt;/strong&gt;: It is the addition of resources to an existing instance or server to increase capacity. No code alterations are required for this type of scaling as you only need to add additional units to expand.
Vertical scaling involves increasing and upgrading your server by adding more CPU cores, hard disks, or solid-state drives to improve the server's memory, storage, network speed, and computing power.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://wa.aws.amazon.com/wellarchitected/2020-07-02T19-33-23/wat.concept.horizontal-scaling.en.html"&gt;Horizontal Scaling&lt;/a&gt;&lt;/strong&gt;: It involves adding several servers or nodes to your existing cloud infrastructure. It is also referred to as scaling out. Where vertical scaling focuses on giving your server stronger CPUs to boost their performance, horizontal scaling deals with increasing the number of servers available. 
While horizontal scaling is more complex and time-consuming than vertical, it pays off in the long run by allowing you to handle traffic efficiently, connect multiple servers, and execute concurrent workloads.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.kamatera.com/Solutions/475/How_it_Works"&gt;Diagonal Scaling&lt;/a&gt;&lt;/strong&gt;: 
It is a combination of vertical and horizontal scaling that is aimed at giving you the best of both worlds. This method handles scaling vertically and horizontally by allowing you to be agile and flexible in scaling up or down. 
It involves upgrading a single server until it reaches its limit and replicating the server's settings and configurations to a new server.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Cloud Scalability vs Elasticity
&lt;/h2&gt;

&lt;p&gt;While cloud scalability and elasticity both deal with the cloud, they have some distinct differences.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Cloud Scalablilty&lt;/th&gt;
&lt;th&gt;Cloud Elasticity&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;It focuses on adjusting resources to meet the expected increase or decrease in workload.&lt;/td&gt;
&lt;td&gt;It deals with meeting a sudden increase or decrease in demand at any given time.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;It involves long-term planning and allocation of resources.&lt;/td&gt;
&lt;td&gt;It is primarily used in situations where there are unexpected spikes or drops in user demand workload.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;It requires the manual allocation of resources.&lt;/td&gt;
&lt;td&gt;It is entirely automated to adjust to the sudden change in demand.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;It enables you to meet long-term and strategic needs.&lt;/td&gt;
&lt;td&gt;It allows you to meet unexpected and short-term.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Why the Need for Scalable Storage?
&lt;/h2&gt;

&lt;p&gt;Scalable storage infrastructures are needed for the following reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Planning&lt;/strong&gt;: While you may not always be able to account for sudden spikes or drops in demand, with scalable storage, you can stay prepared for every demand outcome. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Resource Management&lt;/strong&gt;: With scalable storage, you can rest assured knowing that you only use the resources you need. When traffic is low, you can quickly scale down and reduce the amount of computing power.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Saves Cost&lt;/strong&gt;: Scalable storage solutions are cost-effective and help prevent wastage because you only pay for what you use. Also, you can avoid buying expensive hardware that can become obsolete in a few years.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Improves Performance&lt;/strong&gt;: By enabling you to react quickly to unexpected spikes in demand, scalable storages help boost performance, offering quick response times. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How do you Achieve Cloud Scalability?
&lt;/h2&gt;

&lt;p&gt;Cloud scalability gives you maximum flexibility and helps your business save time and money while also helping you stay agile and competitive. Cloud architecture's scalability is one reason why more businesses are switching from on-premise.&lt;/p&gt;

&lt;p&gt;Here are some strategies and techniques you can deploy to achieve cloud scalability:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Using Virtual Machines (VMs)&lt;/strong&gt;: Cloud scalability is impossible without VMs. You can easily scale and adapt to virtual machines, unlike physical ones. Technological advancements like 5G internet connections boost the efficiency and speed of VMs, making them even more powerful and performant.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Automation&lt;/strong&gt;: Automating tasks like provisioning servers and deployment helps to scale applications quickly without requiring manual input or intervention. This is particularly important when responding to unexpected changes in demand.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Load Balancing&lt;/strong&gt;: This deals with efficiently distributing incoming traffic across a group of servers, also known as a server farm or server pool. Splitting computational workload between multiple servers ensures optimal performance and that no single server overloads from too much strain.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Containerization&lt;/strong&gt;: This is the process of bundling all the components of an application's code into a single package that you can easily scale up or down. Containerized applications don't take up much space, which makes it much easier to scale your deployments. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to Determine Optimal Cloud Scalability
&lt;/h2&gt;

&lt;p&gt;You may need to frequently change your scalable cloud's setup at different times due to fluctuating business needs and the rise or fall of traffic. The question is, how can you know the amount of storage space and processing capacity required?&lt;/p&gt;

&lt;p&gt;This is where continuous performance testing and monitoring come in. Continuously monitoring request volume, response time, memory utilization, and CPU load will help you evaluate your system's current performance. The data gotten back from the test will help you know if you should scale up or down.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where can you find Scalable Solutions?
&lt;/h2&gt;

&lt;p&gt;There are many great vendors out there that offer scalable data storage solutions and Appwrite is one of them.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://appwrite.io/?utm_source=hackmamba&amp;amp;utm_medium=hackmamba-blog"&gt;Appwrite&lt;/a&gt; is an open-source Backend-as-a-Service (BaaS) platform that abstracts and simplifies everyday development tasks behind easy-to-use APIs. It supports web and mobile technologies and Jamstack frameworks like Next.js, Gatsby, and Nuxt.js.&lt;/p&gt;

&lt;p&gt;By utilizing Appwrite's data storage capabilities, you can scale up and down to match your business needs. Appwrite provides maximum performance and eliminates physical servers' cost and maintenance implications.&lt;/p&gt;

&lt;p&gt;Appwrite also has a cloud service called &lt;a href="https://appwrite.io/cloud/?utm_source=hackmamba&amp;amp;utm_medium=hackmamba-blog"&gt;Appwrite Cloud&lt;/a&gt;. It is currently in a closed beta, but you can get early access and cloud credits through the beta program.&lt;/p&gt;

&lt;p&gt;Beyond its extensive data storage system, Appwrite also has other valuable features and functionalities, including databases, cloud functions, and user authentication and management. &lt;/p&gt;

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

&lt;p&gt;Cloud architecture and computing are changing the face of the software industry and how businesses store, manage, and process data. More businesses will continue moving to cloud-based solutions due to their cost-effective approaches to increasing storage and performance.&lt;/p&gt;

&lt;p&gt;Working with a data storage solution that can scale up or down to meet your needs is important. By building with Appwrite, you can rest assured knowing that your data storage needs will be adequately met in response to the requirements of your product.&lt;/p&gt;

&lt;p&gt;As of this writing, Appwrite has over 29,000 stars on &lt;a href="https://github.com/appwrite"&gt;GitHub&lt;/a&gt; and an active developer community on &lt;a href="https://appwrite.io/discord"&gt;Discord&lt;/a&gt;. These stats are great social proof of why leveraging Appwrite and its capabilities is a great choice. &lt;/p&gt;

&lt;p&gt;Appwrite is widely adopted by developers and is an excellent BaaS solution for your data storage needs. &lt;/p&gt;

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

&lt;p&gt;The following resources can help you get started with Appwrite:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://appwrite.io/docs?utm_source=hackmamba&amp;amp;utm_medium=blog&amp;amp;utm_campaign=hackmamba"&gt;Appwrite documentation&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://appwrite.io/docs/getting-started-for-web"&gt;Getting started with Appwrite for web&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>appwrite</category>
      <category>database</category>
      <category>cloud</category>
      <category>webdev</category>
    </item>
    <item>
      <title>You Can Save this Much by Bootstrapping your Backend</title>
      <dc:creator>nefejames</dc:creator>
      <pubDate>Fri, 27 Jan 2023 08:34:01 +0000</pubDate>
      <link>https://forem.com/hackmamba/you-can-save-this-much-by-bootstrapping-your-backend-4if9</link>
      <guid>https://forem.com/hackmamba/you-can-save-this-much-by-bootstrapping-your-backend-4if9</guid>
      <description>&lt;p&gt;So you need to create a backend for your application where you can store sensitive data like passwords and other confidential information and also non-sensitive data like your users' display names. &lt;/p&gt;

&lt;p&gt;More often than not, you don't have an unlimited budget to go with an expensive solution right from the start, and even if you did, you would most likely want to reduce the cost and save as much as possible. &lt;/p&gt;

&lt;p&gt;While money is not the only factor that comes into play when choosing which route to take, it is one of the most major factors since it ultimately determines the sustainability of your choice. &lt;/p&gt;

&lt;p&gt;What are the cost implications of how you build your backend? Is bootstrapping the right choice, or is it cheaper to make it from scratch? &lt;/p&gt;

&lt;p&gt;This article will shed some light on and evaluate how bootstrapping a backend by leveraging a BaaS provider can help you save money as you build. &lt;/p&gt;

&lt;h2&gt;
  
  
  Two Common Approaches to Setting Up a Backend
&lt;/h2&gt;

&lt;p&gt;While there are several ways to create a backend for your application, these two stand out as the most common.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Building a Custom Solution from Scratch&lt;/strong&gt; &lt;br&gt;
A custom backend is great because it gives you the flexibility and freedom to add as many customizations and features as you desire. The downside of building your backend from scratch is that the responsibility of maintaining and handling the infrastructure rests on you. It also comes with higher development costs and a longer time to market.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Bootstrapping with a Backend as a Service&lt;/strong&gt;&lt;br&gt;
Backend as a Service (BaaS) allows you to outsource the building, ownership, and maintenance of backend infrastructure to third-party providers, enabling you to focus on the frontend, and other core aspects of your application. Instead of building a custom backend, you get access to APIs and SDKs you can use to integrate the backend functionality you need.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Baas vs Custom Backend: Factors to Consider
&lt;/h2&gt;

&lt;p&gt;There are multiple factors to consider when choosing the appropriate backend solution that fits your product requirements. Here are some of the factors:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/hackmamba/minimize-time-to-market-ways-to-accelerate-product-development-20kg"&gt;Time to Market&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Stage of the Product&lt;/li&gt;
&lt;li&gt;Ready-to-use Functionalities&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's explore these factors in detail.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Time to Market&lt;/strong&gt;&lt;br&gt;
Here's a simple truth: your target audience doesn't know or care if you use a BaaS or a custom backend. What they want is a product that solves their problems and delivers the best value to them. The sooner you launch your product, the better. Building a custom backend can take 1-3 months and that can be a long time to wait, particularly for highly saturated markets with competitors that launch fast, which is every market.&lt;br&gt;
One benefit of BaaS solutions is that they increase the speed of development and enable you to build faster by eliminating the need to set up servers, provision containers, and write boilerplate code. Studies show that using &lt;a href="https://dev.to/hackmamba/pre-generated-sdk-libraries-that-help-you-build-apps-faster-4fig"&gt;BaaS solutions like Appwrite&lt;/a&gt; have the potential to reduce your development time by 50%.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Stage of the Product&lt;/strong&gt;&lt;br&gt;
When it comes to the proper backend solution for your application, one size doesn't fit all. The stage of your application in the product lifecycle will affect the type of backend infrastructure you choose. &lt;a href="https://dev.to/appwrite/community-spotlight-tvusage-a-digital-wellbeing-app-35ch"&gt;Builders often choose BaaS providers like Appwrite&lt;/a&gt; when their products are in the early to mid stages of development because they are the appropriate solution. For example, you may not want to allocate resources to set up a custom backend when you have few users and very few features available, particularly for a niche product. Besides helping you launch faster, BaaS solutions are a friendlier option for early and mid-stage products, which is how all great applications begin. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Ready-to-use Functionalities&lt;/strong&gt;&lt;br&gt;
BaaS solutions come with multiple features and functionalities baked into them. This means you &lt;br&gt;
are unburdened from looking for third-party services and figuring out how to integrate them into your product. With BaaS solutions like Appwrite, you get access to functionalities like storage, databases, authentication, functions, localization, team access management, and more, all in one platform. Leveraging the ready-made functionalities of Baas solutions means &lt;a href="https://dev.to/hackmamba/dont-re-invent-the-wheel-use-appwrite-3c4b"&gt;you don't have to reinvent the wheel&lt;/a&gt; when building innovative products.&lt;br&gt;
Accessing these services from a single platform is also better because it is easier to manage as you scale compared to integrating and managing multiple third-party vendors when working with a custom backend. It also frees you from the pains of responding to several API changes and updates over time.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Cost to Consider when Choosing between Bootstrapping your Backend or Building from Scratch
&lt;/h2&gt;

&lt;p&gt;When it comes to creating a backend, there are some costs you should consider, as they will ultimately help determine which backend development method you choose to work with.&lt;/p&gt;

&lt;p&gt;Here are some of the cost considerations you should make:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Development Cost&lt;/strong&gt;&lt;br&gt;
Setting up a backend infrastructure is beyond coding. It also involves configuring data storage, hosting, server management, purchasing software licenses, and other responsibilities. The underlying tasks involved make the development of a custom backend expensive. Beyond the financial costs attached, there is also the time cost, as it can take weeks to months to complete the development. &lt;br&gt;
BaaS solutions have no development cost because there is no backend to build. Instead, all you have to do is plug into their service the APIs and SDKs they provide.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Manpower Cost&lt;/strong&gt; &lt;br&gt;
Creating a custom backend requires a lot of resources, regardless of the stage of your product's growth and this includes manpower resources. The fewer features and functionalities you have to code from scratch, the fewer manpower resources you will need.&lt;br&gt;
Since a BaaS system prevents you from reinventing the wheel, fewer hands are needed to build. By limiting the amount of backend work required, BaaS enables you to reduce your manpower cost, which is a good thing because the &lt;a href="https://arc.dev/salaries/back-end-developers" rel="noopener noreferrer"&gt;average global range for a backend developer's salary is $72,484 per year&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cost of Prototyping&lt;/strong&gt;&lt;br&gt;
The idea behind a &lt;a href="https://dev.to/hackmamba/cost-efficient-ways-to-roll-out-your-mvps-and-prototypes-4n27"&gt;Minimum Viable Product (MVP)&lt;/a&gt; is to launch a product as fast as possible while spending little money. BaaS platforms are great for creating proof of concepts and developing MVPs. They give you a lean and efficient setup you can use to launch the initial version of your product. The low-maintenance environment BaaS provides is great for quick prototyping.&lt;br&gt;
Why take months and spend thousands of dollars on your application prototype because you built your backend from scratch when you can achieve the same goal in weeks without spending a dime building with a BaaS provider? &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Maintenance Cost&lt;/strong&gt;&lt;br&gt;
Creating a backend is one thing; maintaining it to ensure optimal performance is another. Many activities go into maintaining a custom backend such as verifying that backups are working, monitoring RAID (Redundant Array of Inexpensive Disks) alarms, updating the OS, and checking for hardware errors and your system's security. These are recurring costs that take time and tons of manpower to handle. &lt;br&gt;
There are no maintenance costs with BaaS solutions because the backend is not your responsibility.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How Much Can You Save by Bootstrapping Your Backend?
&lt;/h2&gt;

&lt;p&gt;Consider a scenario where you need to develop a backend for a SaaS startup with only 100 users. Here are some of the cost implications involved in building the backend from scratch development:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hiring a backend developer costs a minimum of $72,484, and this can increase depending on the developer’s experience. In some cases, a &lt;a href="https://www.ziprecruiter.com/Salaries/Senior-Backend-Developer-Salary" rel="noopener noreferrer"&gt;senior developer’s salary&lt;/a&gt; can be as high as $128,332&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.itsasap.com/blog/server-cost" rel="noopener noreferrer"&gt;Buying a physical server&lt;/a&gt; will cost between $5,000 to $10,000, and &lt;a href="https://www.servermania.com/kb/articles/how-much-does-a-server-cost-for-a-small-business/" rel="noopener noreferrer"&gt;renting a server&lt;/a&gt; will cost between $100 to $200 per month. The SaaS startup will most likely go for renting for starters, then eventually switch to a physical server as they expand &lt;/li&gt;
&lt;li&gt;After buying the server, an IT technician has to install and set it up. This process can take at least 5 hours and costs at least $660&lt;/li&gt;
&lt;li&gt;Carrying out &lt;a href="https://rdi-it.com/how-much-does-a-server-cost-for-a-small-business/" rel="noopener noreferrer"&gt;monthly routine server maintenance&lt;/a&gt; can cost between $150 to $1,500, depending on how frequently the maintenance occurs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All these costs together add up to a range between $78,284 and $139,142 to set up a backend from scratch.&lt;/p&gt;

&lt;p&gt;BaaS solutions eliminate these costs because you don’t have to worry about the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hiring a developer since you have easy-to-use APIs and SDKs for quick integration&lt;/li&gt;
&lt;li&gt;Buying or renting a physical server, since &lt;/li&gt;
&lt;li&gt;Hiring an IT technician because there are no servers to install&lt;/li&gt;
&lt;li&gt;Carry out maintenance because there are no servers to maintain&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, the fact that BaaS platforms are more cost-effective does not mean they do not come with their own cost implications. Most BaaS solutions operate on a pay-as-you-go pricing model where you are charged based on your level of usage. The charge is usually &lt;a href="https://www.developernation.net/blog/baas" rel="noopener noreferrer"&gt;between $0.01 and 0.10 per API call&lt;/a&gt;. They also come with generous free tiers ranging from tens of thousands to a million API calls per month, and sometimes, businesses don’t scale beyond that, meaning they pay nothing and get a backend for free.&lt;br&gt;
With 100 users for the SaaS startup, the backend will cost between $5000 to $1000 per month, at $0.10 per API call. This amount depends on the number of monthly API calls generated by user activity.&lt;/p&gt;

&lt;p&gt;This means that you stand to save at least $68,284 and as much as $129,142 by bootstrapping your backend with a BaaS provider.&lt;/p&gt;

&lt;p&gt;Note that while actual costs may vary from one project to another and between regions, this budget gives you a rough idea of the cost-saving benefits you stand to gain by bootstrapping your backend development.&lt;/p&gt;

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

&lt;p&gt;Creating a great product is complex, and a lot of decision-making goes into the processes involved. Among other things, it is important to consider the nature of your product and the resources available when deciding what backend solution to use. &lt;br&gt;
A great thing about choosing &lt;a href="https://appwrite.io/?utm_source=hackmamba&amp;amp;utm_medium=hackmamba-blog" rel="noopener noreferrer"&gt;Appwrite&lt;/a&gt; as your BaaS provider is that it provides you with the necessary APIs, &lt;a href="https://appwrite.io/docs/sdks" rel="noopener noreferrer"&gt;SDKs&lt;/a&gt;, and functionalities to build great web and mobile applications easily. Appwrite is free and easy to set up. It has comprehensive documentation, a simple learning curve, and a large and supportive community to help assist and get you started quickly.&lt;/p&gt;

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

&lt;p&gt;The following resources can help you get started with bootstrapping your backend with Appwrite:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://appwrite.io/docs?utm_source=hackmamba&amp;amp;utm_medium=blog&amp;amp;utm_campaign=hackmamba" rel="noopener noreferrer"&gt;Appwrite documentation&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://appwrite.io/docs/getting-started-for-web" rel="noopener noreferrer"&gt;Getting started with Appwrite for web&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/hackmamba/cost-efficient-ways-to-roll-out-your-mvps-and-prototypes-4n27"&gt;Cost-Efficient Ways To Roll Out Your MVPs and Prototypes
&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>watercooler</category>
      <category>discuss</category>
    </item>
    <item>
      <title>How to Create a GitHub Profile Application With React and GitHub APIs</title>
      <dc:creator>nefejames</dc:creator>
      <pubDate>Mon, 09 Jan 2023 23:15:07 +0000</pubDate>
      <link>https://forem.com/nefejames/how-to-create-a-github-profile-application-with-react-and-github-apis-3ifl</link>
      <guid>https://forem.com/nefejames/how-to-create-a-github-profile-application-with-react-and-github-apis-3ifl</guid>
      <description>&lt;p&gt;In this article, we will learn how to create an online portfolio showcasing information available in our GitHub profile by leveraging the GitHub API, React, and Chakra UI. &lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Knowledge of React and how to fetch data from APIs is required to follow along in this article. Experience with Chakra UI is a plus but not required.&lt;/p&gt;

&lt;h2&gt;
  
  
  What We Will Build
&lt;/h2&gt;

&lt;p&gt;The GitHub profile application will have the following features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;A &lt;code&gt;/github-profile&lt;/code&gt; route containing basic information about our GitHub account, such as&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The number of repositories available&lt;/li&gt;
&lt;li&gt;The number of followers and following &lt;/li&gt;
&lt;li&gt;A link to our portfolio&lt;/li&gt;
&lt;li&gt;Our location&lt;/li&gt;
&lt;li&gt;Our username&lt;/li&gt;
&lt;li&gt;Our profile picture&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;A &lt;code&gt;/repos&lt;/code&gt; route containing the list of repositories we have on GitHub, and pagination for easier navigation from one set of repositories to another&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;An error boundary route&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;A navigation bar with links to the different routes&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;The images below show a preview of the application we will build. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpaper-attachments.dropboxusercontent.com%2Fs_E24FB436EF76382794006C074BE9E6B59F0AA2BAA5C959DFD91E28C483E6397D_1673290539466_Screenshot%2B3193.png%2520align%3D" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpaper-attachments.dropboxusercontent.com%2Fs_E24FB436EF76382794006C074BE9E6B59F0AA2BAA5C959DFD91E28C483E6397D_1673290539466_Screenshot%2B3193.png%2520align%3D" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpaper-attachments.dropboxusercontent.com%2Fs_E24FB436EF76382794006C074BE9E6B59F0AA2BAA5C959DFD91E28C483E6397D_1673290539112_Screenshot%2B3194.png%2520align%3D" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpaper-attachments.dropboxusercontent.com%2Fs_E24FB436EF76382794006C074BE9E6B59F0AA2BAA5C959DFD91E28C483E6397D_1673290539112_Screenshot%2B3194.png%2520align%3D" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The hosted version of the complete application is on &lt;a href="https://nefe-altschool-github-exam-q1.vercel.app/github-profile" rel="noopener noreferrer"&gt;Vercel&lt;/a&gt;, and the source code is available on &lt;a href="https://github.com/nefejames/altschool-github-exam-app" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

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

&lt;p&gt;Run the command below in the terminal to generate a new React app with create-react-app.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx create-react-app github-profile-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, navigate to the directory and run the server.&lt;br&gt;
&lt;br&gt;
 &lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;github-profile-app

npm start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Finally, &lt;a href="https://chakra-ui.com/getting-started" rel="noopener noreferrer"&gt;install Chakra UI&lt;/a&gt; into the React app.&lt;/p&gt;

&lt;p&gt;Now that the app is ready let’s start building. We will begin with creating the different routes.&lt;/p&gt;
&lt;h2&gt;
  
  
  Setting up the GitHubUser Context
&lt;/h2&gt;

&lt;p&gt;The GitHubUser context will contain details of our GitHub account that we fetch from the GitHub API.&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;createContext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useContext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useState&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="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;GitHubUserContext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createContext&lt;/span&gt;&lt;span class="p"&gt;();&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;useGitHubUserContext&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="nf"&gt;useContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;GitHubUserContext&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;GitHubUserContextProvider&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;GitHubUserData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setGitHubUserData&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;fetchGitHubUserData&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;response&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;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`https://api.github.com/users/nefejames`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nf"&gt;setGitHubUserData&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="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="nf"&gt;fetchGitHubUserData&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;GitHubUserData&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;GitHubUserContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Provider&lt;/span&gt; &lt;span class="nx"&gt;value&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="nx"&gt;children&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;/GitHubUserContext.Provider&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we did the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Imported the necessary dependencies from &lt;code&gt;react&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Created the &lt;code&gt;GitHubUserData&lt;/code&gt; state&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Created the &lt;code&gt;fetchGitHubUserData&lt;/code&gt; function that fetches the user data from the GitHub API&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set up the fetch functionality in the &lt;code&gt;useEffect&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Passed the fetched data as the value of the Context API&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Setting up the GitHubRepos Context and Pagination Functionality 
&lt;/h2&gt;

&lt;p&gt;The GitHubRepos context will contain information on our GitHub repos and their respective details. We will also set up the pagination functionality here.&lt;br&gt;
&lt;br&gt;
 &lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createContext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useContext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useState&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="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;GitHubReposContext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createContext&lt;/span&gt;&lt;span class="p"&gt;();&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;useGitHubReposContext&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="nf"&gt;useContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;GitHubReposContext&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;GitHubReposContextProvider&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;GitHubReposData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setGitHubReposData&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&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;loading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setLoading&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&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;currentPage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCurrentPage&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;totalNoOfPages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;fetchGitHubReposData&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setLoading&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&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;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="s2"&gt;`https://api.github.com/users/nefejames/repos`&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nf"&gt;setGitHubReposData&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="nf"&gt;setLoading&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&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="nf"&gt;fetchGitHubReposData&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;//start pagination functionality setup&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getPaginationData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;currentPage&lt;/span&gt; &lt;span class="o"&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;reposPerPage&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;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;currentPage&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;reposPerPage&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;reposPerPage&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;splice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reposPerPage&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;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;handlePageChange&lt;/span&gt; &lt;span class="o"&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setCurrentPage&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;prevPage&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="nx"&gt;currentPage&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nf"&gt;setCurrentPage&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;prev&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;prev&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&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;nextPage&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="nx"&gt;currentPage&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="nx"&gt;totalNoOfPages&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;setCurrentPage&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;prev&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;prev&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;filteredRepos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getPaginationData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;GitHubReposData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;currentPage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;//end pagination functionality setup&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;filteredRepos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;prevPage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;nextPage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;handlePageChange&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;totalNoOfPages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;currentPage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;GitHubReposContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Provider&lt;/span&gt; &lt;span class="nx"&gt;value&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="nx"&gt;children&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;/GitHubReposContext.Provider&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;We did the following to set up the GitHubRepos context:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Imported the necessary dependencies from react&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Created the &lt;code&gt;GitHubReposData&lt;/code&gt; and the &lt;code&gt;loading&lt;/code&gt; states&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Created the &lt;code&gt;fetchGitHubReposData&lt;/code&gt; function that fetches the repos data from the GitHub API&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set up the fetch functionality in the &lt;code&gt;useEffect&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Passed the fetched data as the value of the Context API&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s break down the functionality for the pagination:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;We created the &lt;code&gt;currentPage&lt;/code&gt; state and set its initial value to 1 because that is what we want the first pagination step to be&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We set up the &lt;code&gt;totalNoOfPages&lt;/code&gt; and set it to 5 because that is the number of steps we want &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;code&gt;prevPage&lt;/code&gt; function only reduces the step if the value of &lt;code&gt;currentPage&lt;/code&gt; is more than 1&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;code&gt;nextPage&lt;/code&gt; function only increases the step if &lt;code&gt;currentPage&lt;/code&gt; is greater than or equal to &lt;code&gt;totalNoOfPages&lt;/code&gt; &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;code&gt;handlePageChange&lt;/code&gt; function updates the &lt;code&gt;currentPage&lt;/code&gt; when anyone clicks on the pagination buttons&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Creating the Pagination Component
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;Pagination&lt;/code&gt; component will hold the pagination buttons. To set it up, create a &lt;code&gt;Pagination.js&lt;/code&gt; file in the components folder and paste the following 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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;HStack&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;@chakra-ui/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;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Pagination&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;onPageChange&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;currentPage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;prevPage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;nextPage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;totalNoOfPages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getPages&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pageNumber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
    &lt;span class="k"&gt;for &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;i&lt;/span&gt; &lt;span class="o"&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;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;totalNoOfPages&lt;/span&gt; &lt;span class="o"&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;i&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;pageNumber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&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;pageNumber&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;HStack&lt;/span&gt; &lt;span class="nx"&gt;spacing&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;mt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;6&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;Button&lt;/span&gt;
        &lt;span class="nx"&gt;disabled&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;currentPage&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;1&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="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;prevPage&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;amp;&lt;/span&gt;&lt;span class="nx"&gt;larr&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;/Button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;getPages&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;page&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;Button&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;page&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="nx"&gt;onClick&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="nf"&gt;onPageChange&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;bg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;currentPage&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;blue.500&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gray.200&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;currentPage&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#fff&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#111&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="nx"&gt;_hover&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;
            &lt;span class="na"&gt;bg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;currentPage&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;blue.500&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="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="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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Button&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="nx"&gt;Button&lt;/span&gt;
        &lt;span class="nx"&gt;disabled&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;currentPage&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;totalNoOfPages&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="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;nextPage&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;amp;&lt;/span&gt;&lt;span class="nx"&gt;rarr&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;/Button&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;/HStack&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s break down the code above:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The Pagination component takes in &lt;code&gt;onPageChange&lt;/code&gt;, &lt;code&gt;currentPage&lt;/code&gt;, &lt;code&gt;prevPage&lt;/code&gt;, nextPage, and &lt;code&gt;totalNoOfPages&lt;/code&gt; as props&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;code&gt;getPages&lt;/code&gt; function gets the current step and returns it in the &lt;code&gt;pageNumber&lt;/code&gt; variable&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We use the values and properties gotten via props to get up the buttons&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Creating the GitHub UserProfile Route
&lt;/h2&gt;

&lt;p&gt;Navigate to the &lt;code&gt;src&lt;/code&gt; folder, and create a &lt;code&gt;pages&lt;/code&gt; folder there. In there, create a &lt;code&gt;GitHubUser.js&lt;/code&gt; file, and update it with the following 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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;GitHubUserAnalytics&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/GitHubUserAnalytics&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;GitHubUserLinks&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/GitHubUserLinks&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;Link&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-router-dom&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;useGitHubUserContext&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;../context/GitHubUserContext&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;LazyLoadImage&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-lazy-load-image-component&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-lazy-load-image-component/src/effects/blur.css&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;PlaceholderImage&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;../images/placeholder.jpg&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;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="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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;GitHubUser&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;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useGitHubUserContext&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;ChakraLink&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;chakra&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Link&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ChakraLazyLoadImage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;chakra&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;LazyLoadImage&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;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Spinner&lt;/span&gt; &lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;xl&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&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;nefejames - GitHub profile&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Front end web developer and technical writer - always learning - nefejames&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;Card&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;Flex&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;Box&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;full&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;300px&lt;/span&gt;&lt;span class="dl"&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ChakraLazyLoadImage&lt;/span&gt;
              &lt;span class="nx"&gt;src&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="nx"&gt;avatar_url&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
              &lt;span class="nx"&gt;placeholderSrc&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;PlaceholderImage&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;Text&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;span&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;mt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;display&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;inline-block&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;teal.900&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="p"&gt;@{&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;login&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;/Text&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;/Box&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;VStack&lt;/span&gt; &lt;span class="nx"&gt;spacing&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;alignItems&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;start&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;VStack&lt;/span&gt; &lt;span class="nx"&gt;spacing&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;alignItems&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;start&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;VStack&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;Text&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;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Text&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;/VStack&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;Text&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;p&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bio&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;/Text&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;/VStack&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;GitHubUserAnalytics&lt;/span&gt;
              &lt;span class="nx"&gt;noOfRepos&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="nx"&gt;public_repos&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
              &lt;span class="nx"&gt;noOfFollowers&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="nx"&gt;followers&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
              &lt;span class="nx"&gt;noOfFollowing&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="nx"&gt;following&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;GitHubUserLinks&lt;/span&gt; &lt;span class="nx"&gt;webUrl&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="nx"&gt;blog&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;location&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="nx"&gt;location&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;ChakraLink&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/repos&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;w&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;full&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;Button&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;View&lt;/span&gt; &lt;span class="nx"&gt;my&lt;/span&gt; &lt;span class="nx"&gt;Repos&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Button&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;/ChakraLink&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;/VStack&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;/Flex&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;/Card&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;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we did the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Imported the relevant dependencies and components &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Passed the appropriate data to &lt;code&gt;noOfRepos&lt;/code&gt;, &lt;code&gt;noOfFollowers&lt;/code&gt;, and &lt;code&gt;noOfFollowing&lt;/code&gt; properties of the &lt;code&gt;GitHubUserAnalytics&lt;/code&gt; component&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Passed the appropriate data to the &lt;code&gt;webUrl&lt;/code&gt; and &lt;code&gt;location&lt;/code&gt; properties of the &lt;code&gt;GitHubUserLinks&lt;/code&gt; component&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code&gt;GitHubUserAnalytics&lt;/code&gt; component displays analytics on our account's number of repositories, followers, and following. &lt;/p&gt;

&lt;p&gt;Here’s the code snippet for it. It takes in the &lt;code&gt;noOfRepos&lt;/code&gt;,  &lt;code&gt;noOfFollowers&lt;/code&gt;, and &lt;code&gt;noOfFollowing&lt;/code&gt; as props from its parent, the &lt;code&gt;GitHubUser&lt;/code&gt; component, and displays them in the UI.&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;Flex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;VStack&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;@chakra-ui/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;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;GitHubUserAnalytics&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;noOfRepos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;noOfFollowers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;noOfFollowing&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Flex&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;VStack&lt;/span&gt; &lt;span class="nx"&gt;spacing&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&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;Text&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;span&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Repos&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Text&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;Text&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;span&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;fontWeight&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bold&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;fontSize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;xl&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;noOfRepos&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;/Text&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;/VStack&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;VStack&lt;/span&gt; &lt;span class="nx"&gt;spacing&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&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;Text&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;span&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Followers&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Text&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;Text&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;span&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;fontWeight&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bold&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;fontSize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;xl&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;noOfFollowers&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;/Text&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;/VStack&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;VStack&lt;/span&gt; &lt;span class="nx"&gt;spacing&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&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;Text&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;span&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Following&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Text&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;Text&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;span&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;fontWeight&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bold&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;fontSize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;xl&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;noOfFollowing&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;/Text&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;/VStack&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;/Flex&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;GitHubUserLinks&lt;/code&gt; component is responsible for displaying the link to our portfolio and our location. &lt;/p&gt;

&lt;p&gt;Here’s the code snippet for it. It takes the &lt;code&gt;webUrl&lt;/code&gt; and &lt;code&gt;location&lt;/code&gt; as props from &lt;code&gt;GitHubUser&lt;/code&gt; and displays them in the UI.&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;HStack&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Text&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;@chakra-ui/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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;BiLink&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;BiMap&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-icons/bi&lt;/span&gt;&lt;span class="dl"&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;GitHubUserLinks&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;webUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;location&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;HStack&lt;/span&gt; &lt;span class="nx"&gt;spacing&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;8&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;a&lt;/span&gt; &lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;webUrl&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;_blank&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;rel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;noopener noreferrer&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;HStack&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;BiLink&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;Text&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;span&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;My&lt;/span&gt; &lt;span class="nx"&gt;portfolio&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Text&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;/HStack&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;/a&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;HStack&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;BiMap&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;Text&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;span&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;location&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;/Text&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;/HStack&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;/HStack&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;SEO&lt;/code&gt; component uses &lt;a href="https://github.com/staylor/react-helmet-async" rel="noopener noreferrer"&gt;react-helmet-async&lt;/a&gt; to set up some basic SEO optimization for the page. It accepts the &lt;code&gt;title&lt;/code&gt; and &lt;code&gt;description&lt;/code&gt; as props.&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;Helmet&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-helmet-async&lt;/span&gt;&lt;span class="dl"&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;SEO&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Front end web developer and technical writer - always learning - nefejames&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="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;Helmet&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;title&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;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;/title&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;meta&lt;/span&gt; &lt;span class="nx"&gt;charset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;utf-8&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;meta&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;theme-color&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#000000&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;meta&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;viewport&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;width=device-width, initial-scale=1&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;meta&lt;/span&gt; &lt;span class="nx"&gt;property&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;og:description&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&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="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;/Helmet&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Creating the Repos Route
&lt;/h2&gt;

&lt;p&gt;The Repos route will handle the display of the list of repositories and the pagination buttons. Create a &lt;code&gt;Repos.js&lt;/code&gt; file in the &lt;code&gt;pages&lt;/code&gt; folder, and copy the code below to set it up.&lt;br&gt;
&lt;br&gt;
 &lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Center&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SimpleGrid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Spinner&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;@chakra-ui/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;Repo&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/Repo&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;useGitHubReposContext&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;../context/GitHubReposContext&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;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="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Pagination&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/Pagination&lt;/span&gt;&lt;span class="dl"&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Repos&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="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;filteredRepos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;prevPage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;nextPage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;handlePageChange&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;totalNoOfPages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;currentPage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useGitHubReposContext&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;loading&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Spinner&lt;/span&gt; &lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;xl&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&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;My Repos&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;SimpleGrid&lt;/span&gt; &lt;span class="nx"&gt;columns&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt; &lt;span class="nx"&gt;spacingX&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;10&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;spacingY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;8&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;pt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;filteredRepos&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;repo&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;Repo&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;repo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="nx"&gt;repoName&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="nx"&gt;progLang&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;repo&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;stars&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stargazers_count&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="p"&gt;))}&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/SimpleGrid&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;Center&lt;/span&gt; &lt;span class="nx"&gt;mb&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;10&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;Pagination&lt;/span&gt;
          &lt;span class="nx"&gt;onPageChange&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handlePageChange&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="nx"&gt;currentPage&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;currentPage&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="nx"&gt;prevPage&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;prevPage&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="nx"&gt;nextPage&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;nextPage&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="nx"&gt;totalNoOfPages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;totalNoOfPages&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;/Center&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;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Here, we did the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Imported the relevant dependencies and components&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Mapped through the &lt;code&gt;filteredRepos&lt;/code&gt;, and displayed the repos in the UI&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Passed the appropriate properties to the &lt;code&gt;Pagination&lt;/code&gt; component&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Creating the Error Boundary Route
&lt;/h2&gt;

&lt;p&gt;Error boundaries help us catch errors that occur anywhere in our application. Create an &lt;code&gt;Error.js&lt;/code&gt; file in the &lt;code&gt;pages&lt;/code&gt; folder, and copy the code below to set it up.&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;Text&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;@chakra-ui/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;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Error&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;error&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Text&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;span&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;An&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="nx"&gt;route&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Text&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Creating the 404 Route
&lt;/h2&gt;

&lt;p&gt;404 routes are instrumental in helping us to catch user-generated navigation errors in our applications. Create a &lt;code&gt;NotFound.js&lt;/code&gt; file in the &lt;code&gt;pages&lt;/code&gt; folder, and copy the code below to set it up.&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;Button&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Center&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;VStack&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;@chakra-ui/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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Link&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-router-dom&lt;/span&gt;&lt;span class="dl"&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;NotFound&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Center&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;VStack&lt;/span&gt; &lt;span class="nx"&gt;spacing&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;5&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;Text&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;h1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;Page&lt;/span&gt; &lt;span class="nx"&gt;not&lt;/span&gt; &lt;span class="nx"&gt;found&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Text&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;Button&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;white&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;bg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;green.900&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;_hover&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;bg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;green.800&lt;/span&gt;&lt;span class="dl"&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Link&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/github-user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;View&lt;/span&gt; &lt;span class="nx"&gt;my&lt;/span&gt; &lt;span class="nx"&gt;GitHub&lt;/span&gt; &lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Link&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;/Button&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;/VStack&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;/Center&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Bringing It All Together
&lt;/h2&gt;

&lt;p&gt;Having created all the necessary components and their respective functionalities, let’s bring them all together in the &lt;code&gt;App.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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Routes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Route&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-router-dom&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;Flex&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;@chakra-ui/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;GitHubUser&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;./pages/GitHubUser&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;Home&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;./pages/Home&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;NotFound&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;./pages/404&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;Header&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/Header&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;Repos&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;./pages/Repos&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="nb"&gt;Error&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;./pages/Error&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;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="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;RepoDetails&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/RepoDetails&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="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&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;My GitHub App&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;Flex&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;Routes&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;Route&lt;/span&gt; &lt;span class="nx"&gt;exact&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;element&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;lt;&lt;/span&gt;&lt;span class="nx"&gt;Home&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;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Route&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/github-profile&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;element&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;lt;&lt;/span&gt;&lt;span class="nx"&gt;GitHubUser&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&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;Route&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;repos&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;element&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;lt;&lt;/span&gt;&lt;span class="nx"&gt;Repos&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&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;/Route&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;Route&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/error&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;element&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;lt;&lt;/span&gt;&lt;span class="nb"&gt;Error&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&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;Route&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;element&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;lt;&lt;/span&gt;&lt;span class="nx"&gt;NotFound&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&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;/Routes&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;/Flex&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;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;App&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;With that, we have successfully created the GitHub profile application. This project was part of the second-semester assessment for &lt;a href="https://www.altschoolafrica.com/" rel="noopener noreferrer"&gt;AltSchool Africa’s&lt;/a&gt; &lt;a href="https://www.altschoolafrica.com/schools/engineering" rel="noopener noreferrer"&gt;Frontend Engineering&lt;/a&gt; track.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>A Beginner’s Guide To A Successful DevRel Career 🥑</title>
      <dc:creator>nefejames</dc:creator>
      <pubDate>Sun, 18 Dec 2022 16:48:41 +0000</pubDate>
      <link>https://forem.com/nefejames/a-beginners-guide-to-a-successful-devrel-career-2el</link>
      <guid>https://forem.com/nefejames/a-beginners-guide-to-a-successful-devrel-career-2el</guid>
      <description>&lt;p&gt;Developer Relations, or DevRel for short, is a role that helps foster healthy and mutually beneficial relationships between companies and software developers. It is a field that has grown in popularity in the last few years as more companies pay attention to product advocacy and awareness in the developer community. &lt;/p&gt;

&lt;p&gt;This article will cover the genesis and history of DevRel, its current state, mistakes to avoid, and how to build a career in DevRel successfully.&lt;/p&gt;

&lt;h2&gt;
  
  
  The History of DevRel
&lt;/h2&gt;

&lt;p&gt;The DevRel we know and love today was not a thing a few years ago. As of 2017, what we had were conferences and meetups among tech enthusiasts who shared the same interest and love for specific tools and technologies. Developers arranged local and international meetings and talked about things they've been learning, cool projects they built, the process involved in a problem they solved at work or home, and how they used specific tools, APIs, and resources to solve said problem. This was the genesis of DevRel—community; people gathering together and educating one another.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Current State of DevRel
&lt;/h2&gt;

&lt;p&gt;The demand for DevRel experts and professionals has increased over time. Sadly, that is not the only change that has come to the DevRel space in recent times.&lt;/p&gt;

&lt;p&gt;The focus of DevRel has always been education. In fact, DevRel became successful because people made education their priority. No one was trying to market their company, bring in sales, get signups, drive adoption, or push and promote their company's products into people's faces. Instead, the focus was on sharing challenges and lessons learned while building great products. &lt;/p&gt;

&lt;p&gt;DevRel has transitioned from education to marketing, sales, and adoption. Company leadership needs to remember that developers don't spend their time, money, and energy attending conferences to watch or listen to some product promotion. Instead, they come to learn. No one pays money to hear you advertise your company and talk about why your solution and services are the best in the world. &lt;/p&gt;

&lt;p&gt;DevRel was a group of enthusiasts coming together to share their joy, and that must become the focus once again. &lt;/p&gt;

&lt;h2&gt;
  
  
  The Modes of DevRel
&lt;/h2&gt;

&lt;p&gt;As stated earlier in this article, education is the core of DevRel. There are four major modes through which this can be accomplished, and they are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Speaking&lt;/li&gt;
&lt;li&gt;Writing&lt;/li&gt;
&lt;li&gt;Video Content Creation&lt;/li&gt;
&lt;li&gt;Conducting Workshops&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Having experience in at least one of these modes is highly recommended. Also, consider growing in other modes over time as part of your career development goals. &lt;/p&gt;

&lt;p&gt;There is no hard rule when it comes to choosing the mode to focus on first. No one is more important than another. A great way to decide is by picking the mode you are highly interested in. For example, if you naturally enjoy writing, consider selecting the writing mode, as you are more likely to deliver stellar results and improve faster with that than with other modes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tips To Set Yourself up for Success in DevRel
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Participate in Local Meetups&lt;br&gt;
Local meetups are a great way to get your foot wet and gain practical DevRel experience. Often, it is also a great way to beef up your portfolio, carve a niche for yourself, show your talent, and ultimately gain access to international audiences. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Don't Make Relationships Transactional&lt;br&gt;
Avoid transaction relationships; people can often smell opportunists from a mile away. Trying to use people for their followership, connections, network and what you can gain from them is a sin in the DevRel space. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Be Open-minded&lt;br&gt;
Be open to trying new opportunities, attending new conferences, and forming new connections. Great things could come from these moments later in the future.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;De-godify People&lt;br&gt;
Don't feel like there are people you can't talk to or be in the same space with. No matter their achievements, they are just humans like you! &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Support People&lt;br&gt;
Find out what people are creating and the problems they are trying to solve, then see how you can support them in reaching their goals. This is a great way to form genuine connections. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Have Great Communication Skills&lt;br&gt;
When it comes to DevRel, communication is worth its weight in gold. Great developer advocates put a lot of thought into their communication, and it shows in the materials they put out, whether it's a GitHub readMe, YouTube video, or a 1000-word article. It is important to communicate in a way that anyone who comes across your work will understand. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Have Some Developer Experience&lt;br&gt;
While you don't have to be a 10x developer, some level of developer knowledge and experience is required to truly connect with other developers and speak their language. The more technical expertise and experience you have, the better, which is an advantage that will make you more effective. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Have An Active Online Presence&lt;br&gt;
Constantly publish content to social media platforms (YouTube, Twitter, Hashnode, etc.) via your chosen teaching mode. It's a great way to stay consistent and deliver content to your audience.&lt;br&gt;
The key to having an active presence on any platform is sharing and talking about the things you enjoy doing. Consistency is easier when delight is present in an activity. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Measure Your Growth&lt;br&gt;
Analyze your work overtime to ensure you've been growing. Have the quality of your videos gotten better? Have your oratory skills improved? Is your writing more structured and concise? Tracking these parts of your skillset allows you to spot growth or areas that require improvements. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Remember that it's DevRel, Not DevSell&lt;br&gt;
Always remember that the essence of DevRel is not sales or marketing. Those are the job of the sales and marketing teams. Instead, DevRel is fundamentally about providing value, growing relationships, and educating your audience. &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;Now you have all you need to succeed in DevRel; have a fruitful and impactful career. &lt;/p&gt;

</description>
      <category>discuss</category>
      <category>community</category>
      <category>learning</category>
      <category>developers</category>
    </item>
    <item>
      <title>How to Build Applications With Fewer APIs Bundling</title>
      <dc:creator>nefejames</dc:creator>
      <pubDate>Tue, 29 Nov 2022 17:34:07 +0000</pubDate>
      <link>https://forem.com/hackmamba/how-to-build-applications-with-fewer-apis-bundling-5d69</link>
      <guid>https://forem.com/hackmamba/how-to-build-applications-with-fewer-apis-bundling-5d69</guid>
      <description>&lt;p&gt;As a developer, you have many decisions to make when building awesome software products. You have to choose a tech stack, define project scope and restraints, test and deployment strategies, decide on GitHub workflows, define coding style guides, etc. &lt;/p&gt;

&lt;p&gt;As important as these decisions are, you must also choose between building every functionality from scratch or leveraging Application Programming Interfaces (APIs) to lighten the load. Most people often choose the latter option because &lt;a href="https://dev.to/hackmamba/dont-re-invent-the-wheel-use-appwrite-3c4b"&gt;building with existing solutions is better than re-inventing the wheel&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Upon deciding to use APIs, you’ll encounter the challenge of finding the ideal APIs that meet product requirements and provide the functionalities you need. In cases where a single API doesn't meet your needs, you patch and combine multiple APIs to achieve the required result. Not only is this time-consuming, but it is also difficult to maintain and prone to errors and bugs in the long run, particularly when API versions change.&lt;/p&gt;

&lt;p&gt;This article will explore factors to consider when choosing the right APIs. You will also learn how &lt;a href="https://appwrite.io/?utm_source=hackmamba&amp;amp;utm_medium=hackmamba-blog"&gt;Appwrite&lt;/a&gt; solves the issue of sourcing for and bundling multiple APIs with the numerous APIs and points of integration they offer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Factors to Consider When Choosing the Right API Provider
&lt;/h2&gt;

&lt;p&gt;These are some critical factors you should consider when choosing an API service.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ease of integration&lt;/li&gt;
&lt;li&gt;Variety of services&lt;/li&gt;
&lt;li&gt;Active developer community&lt;/li&gt;
&lt;li&gt;Documentation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s study these factors in detail:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ease of&lt;/strong&gt; &lt;strong&gt;I&lt;/strong&gt;&lt;strong&gt;ntegration&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Time is invaluable when building projects and an API's ease of integration goes a long way to speed up or delay development. Beyond APIs, you may want to strongly consider third-party services that provide language-specific and environment-specific Software Development Kits (SDKs) for faster integration. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Variety of&lt;/strong&gt; &lt;strong&gt;S&lt;/strong&gt;&lt;strong&gt;ervices&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The more services an API platform provides, the better. One system with all the functionality you need, whether authentication, database, storage, geolocation, etc., is better than using multiple platforms for different functionalities. &lt;br&gt;
A one-system integration means you only need to learn one API platform, making dealing with bugs and version changes easier over time.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Active&lt;/strong&gt; &lt;strong&gt;D&lt;/strong&gt;&lt;strong&gt;eveloper&lt;/strong&gt; &lt;strong&gt;C&lt;/strong&gt;&lt;strong&gt;ommunity&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Since no man is an island, you should consider if the third-party APIs you want to choose has an &lt;a href="https://dev.to/hackmamba/top-7-discord-servers-every-developer-should-join-59nd"&gt;active developer community&lt;/a&gt; that can assist when needed. Platforms like Stack Overflow are invaluable resources to developers, particularly when dealing with bugs and stubborn issues. You can also gain inspiration from other developers in the communities by observing how they build with and integrate the APIs. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Documentation&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It won't matter how many APIs a provider has or the number of services available if they have poor documentation. Ensure that the documentation covers how the API works, explains the integration process, and has helpful code snippets and sample projects.&lt;br&gt;
Be careful not to choose a provider with poorly written documentation that does not provide comprehensive information on these core points.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Better Way to Build
&lt;/h2&gt;

&lt;p&gt;What if a platform had all the necessary APIs for everyday application development tasks, such as user management, file storage, email sending, authentication, and more? &lt;a href="https://appwrite.io/?utm_source=hackmamba&amp;amp;utm_medium=hackmamba-blog"&gt;Appwrite&lt;/a&gt; is that platform, and it is a self-hosted Backend as a Service (BaaS) platform that provides developers with all the core APIs you need to build any application.&lt;/p&gt;

&lt;p&gt;Appwrite provides ready-to-use APIs that make life easier for developers and end the hunt for reliable and efficient API services.&lt;/p&gt;

&lt;h2&gt;
  
  
  Appwrite's API Offerings
&lt;/h2&gt;

&lt;p&gt;Appwrite provides the following REST APIs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Account API&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;a href="https://appwrite.io/docs/client/account"&gt;Account API&lt;/a&gt; enables you to register and manage new user accounts. You can also use this service to update user information, retrieve user sessions across multiple devices, perform phone verification, and more.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Teams API&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;a href="https://appwrite.io/docs/client/teams?sdk=web-default"&gt;Teams API&lt;/a&gt; allows you to manage and group users in your project. You can share read and write access to project resources like database documents or storage files. It gives you authorization control by enabling you to decide the access privileges of every user.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Database API&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can use the &lt;a href="https://appwrite.io/docs/client/databases"&gt;Database API&lt;/a&gt; to create a structured collection of documents to manage, filter, apply advanced queries, and set permissions. The Databases service returns data as structured JSON documents and you can have as many databases as you need.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Storage API&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Integrating with the Storage API allows you to add file management functionality to your applications, like uploading, viewing, downloading, and querying files. This API has a &lt;a href="https://appwrite.io/docs/client/storage?sdk=web-default#storageGetFilePreview"&gt;preview endpoint&lt;/a&gt; which you can use to generate preview images for your files.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Functions API&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can extend the functionality of Appwrite by creating custom cloud functions with the &lt;a href="https://appwrite.io/docs/client/functions"&gt;Functions API&lt;/a&gt;. Appwrite will trigger these functions when events like account creations, user logins, file uploads, etc., occur. The functions can be executed synchronously and asynchronously. Read more about the latest updates and &lt;a href="https://dev.to/appwrite/building-custom-cloud-functions-using-nodejs-with-appwrite-1bh1"&gt;how you can use the Functions API&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Localization API&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;a href="https://appwrite.io/docs/client/locale?sdk=web-default"&gt;Locale API&lt;/a&gt; gives you information on your user's location, IP address, list of countries and continents names, phone codes, currencies, and more. You can then utilize this data to create a customized experience for your users, like welcoming or sending emails in different languages, displaying weather forecasts, or creating a currency converter.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Avatars API&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;a href="https://appwrite.io/docs/client/avatars?sdk=web-default"&gt;Avatars API&lt;/a&gt; handles images, icons, and avatars in applications. You can use it to fetch country flags, display browser icons, show credit card logos, display name credentials as user profile icons, and more. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Health API&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;a href="https://appwrite.io/docs/server/health"&gt;Health API&lt;/a&gt; lets you check and monitor that your Appwrite server instance and its internal components are up and responsive.&lt;/p&gt;

&lt;p&gt;Appwrite's documentation covers the client-side and server-side implementation of their APIs, with multiple code snippets and use cases available. &lt;/p&gt;

&lt;h2&gt;
  
  
  Appwrite's SDKs - A Richer Developer Experience
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://appwrite.io/?utm_source=hackmamba&amp;amp;utm_medium=hackmamba-blog"&gt;Appwrite&lt;/a&gt; is an incredible platform that has provided several APIs covering many use cases and development scenarios.&lt;br&gt;
However, they didn't stop there. They decided to improve the developer experience by providing SDKs for faster integration. The SDKs are grouped into client and server SDKs and cover different platforms and programming languages.&lt;/p&gt;

&lt;p&gt;The client SDKs are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Web SDK&lt;/li&gt;
&lt;li&gt;Flutter SDK&lt;/li&gt;
&lt;li&gt;Apple SDK&lt;/li&gt;
&lt;li&gt;Android SDK&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The server SDKs are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Node &lt;/li&gt;
&lt;li&gt;Deno&lt;/li&gt;
&lt;li&gt;PHP&lt;/li&gt;
&lt;li&gt;Python&lt;/li&gt;
&lt;li&gt;Ruby&lt;/li&gt;
&lt;li&gt;Dart&lt;/li&gt;
&lt;li&gt;Kotlin&lt;/li&gt;
&lt;li&gt;Swift&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://appwrite.io/docs/sdks"&gt;Learn more about the SDKs&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why You Should Use Appwrite's APIs
&lt;/h2&gt;

&lt;p&gt;These are some reasons why you should build with Appwrite's APIs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They are free and easy to use&lt;/li&gt;
&lt;li&gt;They are reliable, as &lt;a href="https://status.appwrite.io/"&gt;Appwrite has a very high uptime&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;They have a low learning curve &lt;/li&gt;
&lt;li&gt;Access to a large and supportive developer community for assistance&lt;/li&gt;
&lt;li&gt;There are APIs and SDKs for several programming languages and environments&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Appwrite is a developer-friendly platform that empowers web, mobile, and Flutter developers to build with ease. &lt;a href="https://appwrite.io/?utm_source=hackmamba&amp;amp;utm_medium=hackmamba-blog"&gt;Appwrite&lt;/a&gt; ends the problems and inefficiencies of sourcing for and bundling different third-party APIs services by providing numerous API offerings and SDKs for seamless integration. &lt;/p&gt;

&lt;p&gt;With Appwrite, you can focus on building instead of spending time struggling with APIs.&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://appwrite.io/docs/sdks"&gt;Appwrite’s SDKs&lt;/a&gt;&lt;br&gt;
&lt;a href="https://appwrite.io/docs?utm_source=hackmamba&amp;amp;utm_medium=blog&amp;amp;utm_campaign=hackmamba"&gt;Appwrite’s Documentation&lt;/a&gt;&lt;br&gt;
&lt;a href="https://appwrite.io/discord"&gt;Appwrite’s Discord community&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>api</category>
      <category>appwritehack</category>
    </item>
    <item>
      <title>All You Need to Know About Serverless Functions and the Edge</title>
      <dc:creator>nefejames</dc:creator>
      <pubDate>Fri, 25 Nov 2022 21:59:43 +0000</pubDate>
      <link>https://forem.com/nefejames/all-you-need-to-know-about-serverless-functions-and-the-edge-2bl2</link>
      <guid>https://forem.com/nefejames/all-you-need-to-know-about-serverless-functions-and-the-edge-2bl2</guid>
      <description>&lt;p&gt;The technological advancements and digital revolutions of the last century have completely transformed customers' appetites. They expect digital services and platforms to provide them with blazing-fast services and a seamless user experience. Hence, it is essential to build software applications in a way that allows us to meet the expectations and requirements of today’s fast-paced society.&lt;/p&gt;

&lt;p&gt;It is vital to utilize today's innovations to build products for the people of today. Serverless functions and the Edge are powerful technologies we can harness to build speed and scale into our applications and software products. They enable us to deliver content and services to people in a fast and cost-effective manner.&lt;/p&gt;

&lt;p&gt;In this article, we will learn more about serverless functions and the Edge, their benefits, and how to work with them.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are Serverless Functions?
&lt;/h2&gt;

&lt;p&gt;Serverless functions are specific and modular pieces of logic that run on the cloud and are designed to perform a single action. With serverless functions, we can use global data centers to run backend code without needing to configure or maintain servers ourselves, hence the term ‘&lt;em&gt;serverless&lt;/em&gt;’ functions.&lt;/p&gt;

&lt;p&gt;Having said that, technically speaking, servers are still involved, just not ours. Some businesses provide the cloud computing infrastructure that makes this possible, but more on that later. We can deploy serverless functions to multiple regions across the globe to improve latency and availability.&lt;/p&gt;

&lt;p&gt;With serverless functions, we can add all kinds of functionality to applications, such as database queries, form submissions, authentication, and more.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are the Edge and Edge Functions?
&lt;/h2&gt;

&lt;p&gt;The Edge refers to the CDN server or data center closest to the user. We can take serverless functions to the next step by combining them with the Edge to create “Edge functions,” which are serverless functions that run at the Edge.&lt;/p&gt;

&lt;p&gt;Edge functions allow us to modify network requests and serve content from the CDN server that is closest to the users who made the requests, no matter where they are around the globe. We can leverage edge functions to bring unique and personalized experiences to users, like showing localized content, displaying relevant ads, and more.&lt;/p&gt;

&lt;p&gt;Edge functions enable us to deliver functions not within a broad area but in the location closest to the user. By running at the Edge, edge functions boost the performance of applications by providing blazingly fast execution times and low latency.&lt;/p&gt;

&lt;h2&gt;
  
  
  Benefits of Serverless Functions
&lt;/h2&gt;

&lt;p&gt;Here are some benefits of serverless functions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;No infrastructure to manage:&lt;/strong&gt; &lt;br&gt;
Serverless functions eliminate the complexity behind setting up and managing server infrastructure since we don’t need to do that ourselves.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Greater productivity&lt;/strong&gt;&lt;br&gt;
Serverless functions enable us to focus on what matters, writing code and building awesome products. They eliminate the hassle of setting up servers ourselves, meaning we don’t have to spend time picking the right operating system, configuring networks, packing dependencies, handling hardware upgrades, provisioning capacity to run at scale, or any form of DevOps activity. The cloud takes care of that for us behind the scenes, meaning we are free to spend time on priority activities.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Easier to scale&lt;/strong&gt;&lt;br&gt;
As traffic increases or decreases, serverless functions automatically scale up and demand to adjust to the ever-changing rate of usage and avoid downtime.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Lower cost&lt;/strong&gt;&lt;br&gt;
A server-based approach requires tons of manpower, specialized knowledge, and servers to set up, which are expensive, particularly when making provision for high-traffic usage. Serverless functions cost less to operate because we are charged per request platforms charge customers per request and only pay for the resources we consume to run the functions. It also eliminates the costs of idle CPU time or unused storage space because we don’t own any of that infrastructure.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Less Code&lt;/strong&gt;&lt;br&gt;
Since we don’t need to set up the servers ourselves, we also don’t need to write any server-side or backend code. This makes the barrier of entry low for developers because we can add full-stack functionality to applications without needing to know the backend or server side of things.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Faster time to market&lt;/strong&gt;&lt;br&gt;
The serverless approach means we can develop applications and add functionalities faster. This translates to fewer errors, bug fixes, legacy code, and a faster time to market.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Platforms that Support Serverless Functions
&lt;/h2&gt;

&lt;p&gt;As we saw earlier, serverless functions are not truly serverless. They do need servers to function, just not ours, and there are platforms that provide the infrastructure where we can deploy these functions.&lt;/p&gt;

&lt;p&gt;These are some frameworks that support serverless functions.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Vercel exports Next.js API routes as &lt;a href="https://vercel.com/docs/concepts/functions/serverless-functions#deploying-serverless-functions" rel="noopener noreferrer"&gt;serverless functions&lt;/a&gt;. Beyond those, Vercel also &lt;a href="https://vercel.com/docs/concepts/functions/edge-functions" rel="noopener noreferrer"&gt;supports edge functions&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;With &lt;a href="https://www.netlify.com/products/functions/" rel="noopener noreferrer"&gt;Netlify functions&lt;/a&gt;, we can deploy server-side code as API endpoints. It supports functions created with JavaScript, TypeScript, and Go. Like Vercel, Netlify also supports &lt;a href="https://www.netlify.com/products/#netlify-edge-functions/" rel="noopener noreferrer"&gt;edge functions&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://aws.amazon.com/lambda/" rel="noopener noreferrer"&gt;AWS Lambda&lt;/a&gt; is Amazon Web Services’ serverless functions offering, and it is widely adopted by companies. It also has its Edge offering tagged &lt;a href="https://aws.amazon.com/lambda/edge/" rel="noopener noreferrer"&gt;AWS Lambda@Edge&lt;/a&gt;.
&lt;a href="https://aws.amazon.com/lambda/" rel="noopener noreferrer"&gt;&lt;/a&gt;- &lt;a href="https://azure.microsoft.com/en-us/products/functions/#features" rel="noopener noreferrer"&gt;Microsoft Azure Functions&lt;/a&gt; is a serverless environment on Azure. It supports programming languages like C#, JavaScript, Java, Python, TypeScript, etc.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://cloud.google.com/functions" rel="noopener noreferrer"&gt;Google Cloud Functions&lt;/a&gt; is Google’s serverless environment. It supports programming languages like JavaScript, Python, and Go.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://cloud.ibm.com/functions" rel="noopener noreferrer"&gt;IBM Cloud Functions&lt;/a&gt; is a Functions-as-a-Service (FaaS) platform for developing lightweight code that executes at scale and on demand.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://supabase.com/edge-functions" rel="noopener noreferrer"&gt;Supabase functions&lt;/a&gt; can be distributed to 29 geographic region globally, and it is written in TypeScript.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://workers.cloudflare.com/" rel="noopener noreferrer"&gt;CloudFlare Workers&lt;/a&gt; is Cloudflare’s serverless offering, and it runs on Chrome’s V8 engine under the hood.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.oracle.com/cloud/cloud-native/functions/" rel="noopener noreferrer"&gt;Oracle Cloud Functions&lt;/a&gt; supports Python, Go, Java, Node, and other languages.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Frameworks That Support Serverless Functions
&lt;/h2&gt;

&lt;p&gt;These are some frameworks that support serverless functions.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Next.js provides &lt;a href="https://nextjs.org/docs/api-routes/introduction" rel="noopener noreferrer"&gt;API routes&lt;/a&gt; that we can deploy as serverless functions on Vercel and other platforms. Also, it’s built by Vercel, so it fully supports serverless functions.&lt;/li&gt;
&lt;li&gt;SvelteKit comes with an &lt;a href="https://vercel.com/docs/beginner-sveltekit/endpoints" rel="noopener noreferrer"&gt;Endpoints feature&lt;/a&gt; for creating serverless functions, and it also has &lt;a href="https://www.netlify.com/blog/sveltekit-with-netlify-edge-functions/" rel="noopener noreferrer"&gt;Netlify adapter&lt;/a&gt;. With Rich Harris, the creator of Svelte and SvelteKit, being part of the Vercel team, we can hope that SvelteKit will begin to support Vercel functions.&lt;/li&gt;
&lt;li&gt;Remix was recently made an open-source project, and it supports &lt;a href="https://remix.run/blog/remix-and-the-edge" rel="noopener noreferrer"&gt;edge and serverless functions&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://deno.com/deploy" rel="noopener noreferrer"&gt;Deno deploy&lt;/a&gt; enables the deployment of JavaScript, TypeScript, and WebAssembly code at the Edge. In fact, Supabase Functions and Netlify Edge are built with Deno. Also, Deno &lt;a href="https://deno.land/x/azure_functions@v0.9.0" rel="noopener noreferrer"&gt;supports Azure functions&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Anatomy of a Serverless Function
&lt;/h2&gt;

&lt;p&gt;We’ve looked at a lot of the theoretical aspects surrounding serverless functions. However, let’s also take a brief glimpse of how an edge function looks.&lt;/p&gt;

&lt;p&gt;We’ll create a function that adds a record to a Xata database.&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;getXataClient&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;@utils/xata&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;xata&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getXataClient&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;handler&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;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&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;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;price&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;imgUrl&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&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="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;xata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Products&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;price&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;img&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;imgUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;end&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;handler&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Serverless functions make HTTP requests and then send a response back. They have two arguments, a request (&lt;code&gt;req&lt;/code&gt;), and a response &lt;code&gt;(res&lt;/code&gt;). Basically, we write a function, deploy it to a serverless provider, then we can call that function just like any API using HTTP methods, the fetch API, or our preferred method of fetching data.&lt;/p&gt;

&lt;p&gt;Note that the structure of edge functions may look slightly different depending on the platform and provider we use. However, they will generally have little differences and similar functions and behaviors.&lt;/p&gt;

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

&lt;p&gt;Serverless functions and the Edge have had a positive impact on builders and consumers alike. Builders can build faster, more effectively, and cheaper, and consumers can get the best experience no matter where they live. &lt;br&gt;
However, ingenuity is never-ending, and progress is not static, so who knows what next technological innovation will transform the experience of the web and how we build with it&lt;br&gt;
However, ingenuity is never-ending, and progress is not static, so who knows what next technological innovation will transformation the experience of the web and how we build with it.&lt;/p&gt;

</description>
      <category>serverlessfunctions</category>
      <category>edge</category>
      <category>performance</category>
    </item>
    <item>
      <title>Create an Ecommerce Admin App with Xata and Cloudinary</title>
      <dc:creator>nefejames</dc:creator>
      <pubDate>Wed, 23 Nov 2022 09:26:04 +0000</pubDate>
      <link>https://forem.com/hackmamba/create-an-ecommerce-admin-app-with-xata-and-cloudinary-2b</link>
      <guid>https://forem.com/hackmamba/create-an-ecommerce-admin-app-with-xata-and-cloudinary-2b</guid>
      <description>&lt;p&gt;Content is king, and behind every content is the CMS (Content Management System), which is the queen. CMSs revolutionalized how we store, produce, and share content. Today, there are a variety of content management solutions, whether traditional, headless or hybrid.&lt;/p&gt;

&lt;p&gt;In this article, we‘ll learn how to create a dummy ecommerce store CMS admin with Next.js, Cloudinary's Upload widget, and Xata.&lt;/p&gt;

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

&lt;p&gt;Access the source code for the application on &lt;a href="https://github.com/nefejames/hackmamba-ecom-admin-app/?utm_source=hackmamba&amp;amp;utm_campaign=hackmamba-hackathon&amp;amp;utm_medium=hackmamba-blog" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;To follow along with this article, we need to have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Knowledge of React and Next.js&lt;/li&gt;
&lt;li&gt;A &lt;a href="https://cloudinary.com/console/?utm_source=hackmamba&amp;amp;utm_campaign=hackmamba-hackathon&amp;amp;utm_medium=hackmamba-blog" rel="noopener noreferrer"&gt;Cloudinary account&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;A &lt;a href="https://app.xata.io/signin/?utm_source=hackmamba&amp;amp;utm_campaign=hackmamba-hackathon&amp;amp;utm_medium=hackmamba-blog" rel="noopener noreferrer"&gt;Xata account&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Understanding of Chakra UI is advantageous but not required&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What Is Xata?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://xata.io/?utm_source=hackmamba&amp;amp;utm_campaign=hackmamba-hackathon&amp;amp;utm_medium=hackmamba-blog" rel="noopener noreferrer"&gt;Xata&lt;/a&gt; is a serverless database built on top of PostgreSQL and Elasticsearch. It comes with useful integrations with popular frameworks and technologies like Next.js, Netlify, Nuxt.js, Vercel, Remix, and SvelteKit.&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://cloudinary.com/?utm_source=hackmamba&amp;amp;utm_campaign=hackmamba-hackathon&amp;amp;utm_medium=hackmamba-blog" rel="noopener noreferrer"&gt;Cloudinary&lt;/a&gt; is a cloud-based and end-to-end platform with tools and functionalities for storing, processing, editing, managing, delivering, and transforming media assets.&lt;/p&gt;

&lt;h2&gt;
  
  
  What We Will Create
&lt;/h2&gt;

&lt;p&gt;The screenshots below shows the application we will create. &lt;br&gt;
Users can add new products by filling in the name, price and image of the products. They can also delete products or update the products’ details.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Ft9g9tpi8de57z1fx8y60.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Ft9g9tpi8de57z1fx8y60.PNG" alt="Products page" width="800" height="337"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fp8zhvv5daanh528p5qt7.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fp8zhvv5daanh528p5qt7.PNG" alt="Product’s detail page" width="800" height="347"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;Download, clone, or fork &lt;a href="https://github.com/nefejames/hackmamba-ecom-admin-app-ui/?utm_source=hackmamba&amp;amp;utm_campaign=hackmamba-hackathon&amp;amp;utm_medium=hackmamba-blog" rel="noopener noreferrer"&gt;this starter template&lt;/a&gt; that contains the code for the UI of the ecommerce admin.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    npx create-next-app xata-cloudinary-chat-app -e https://github.com/nefejames/hackmamba-ecom-admin-app-ui
    or
    yarn create next-app xata-cloudinary-chat-app -e https://github.com/nefejames/hackmamba-ecom-admin-app-ui
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, navigate to the project directory, install the necessary dependencies, then run the application&lt;/p&gt;

&lt;p&gt;The starter template consists of the following files:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;components/AddProductForm.js&lt;/code&gt;: responsible for adding a new product to the shop&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;components/ProductCard.js&lt;/code&gt;: displays a product’s details&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;components/ProductModal.js&lt;/code&gt;: the modal that holds the form&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;components/UpdateProductForm.js&lt;/code&gt;: responsible for updating a product’s details&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;layout/index.js&lt;/code&gt;: the layout for the application&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;utils&lt;/code&gt;: will hold the Xata instance, and the logic for the product image upload and product deletion&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Setting up Xata Database
&lt;/h2&gt;

&lt;p&gt;We start by creating a new database called &lt;strong&gt;chat-app&lt;/strong&gt; on our Xata account.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fkw06i8b6dovsbkjcd3lu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fkw06i8b6dovsbkjcd3lu.png" alt="creating a new Xata database" width="800" height="352"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, create a &lt;code&gt;Products&lt;/code&gt; table that will contain the data of different products. Each record will have &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;price&lt;/code&gt;, &lt;code&gt;img&lt;/code&gt;, and &lt;code&gt;id&lt;/code&gt; properties; the &lt;code&gt;id&lt;/code&gt; is automatically generated by Xata.&lt;br&gt;
We got the images from the media filesuploads in our Cloudinary account.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fg1c3tguaw4clc51hh9qv.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fg1c3tguaw4clc51hh9qv.PNG" alt="create the Products table" width="800" height="317"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The database schema is ready, so let’s set up the Xata instance next, and integrate it into the application. &lt;/p&gt;
&lt;h2&gt;
  
  
  Setting up Xata Instance
&lt;/h2&gt;

&lt;p&gt;Run the command below to install the CLI globally.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    npm install @xata.io/cli -g
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, run &lt;code&gt;xata auth login&lt;/code&gt;, which will prompt you to Create a new API key in the browser or use an existing one; we’ll go with the first option.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F3zwmmfw2qrf057ea8rlm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F3zwmmfw2qrf057ea8rlm.png" alt="Xata auth login" width="800" height="285"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once in the browser, give the API a name and click the &lt;strong&gt;Create API key&lt;/strong&gt; button.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fuz17dsiieq61jq2b3tc8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fuz17dsiieq61jq2b3tc8.png" alt="create a new Xata API key" width="800" height="284"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Back on the dashboard, click on the &lt;strong&gt;Get Code Snippet&lt;/strong&gt; button at the top right corner and copy the second command. We will use it to initialize the project locally with the aid of the CLI.&lt;/p&gt;

&lt;p&gt;Run the command in the terminal and choose from the configuration options. The screenshot below shows the configurations for this application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fp10ww905uve046h0z4hm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fp10ww905uve046h0z4hm.png" alt="Xata CLI config" width="800" height="216"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The CLI will automatically create a &lt;code&gt;xata.js&lt;/code&gt; file that contains the &lt;code&gt;XataClient&lt;/code&gt; instance we need; let’s move on to the coding aspects of the application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up the API Routse
&lt;/h2&gt;

&lt;p&gt;We need to set up these 3 API (Application Programming Interface) routes for the app:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;api/add-product.js&lt;/code&gt;: contains the logic for adding a product to the &lt;code&gt;Products&lt;/code&gt; database&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;api/update-product.js&lt;/code&gt;: contains the logic for updating the information of a product on the &lt;code&gt;Products&lt;/code&gt; database&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;api/delete-prduct.js&lt;/code&gt;: contains the logic for deleting a product on the &lt;code&gt;Products&lt;/code&gt; database&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The code for the &lt;code&gt;add-product.js&lt;/code&gt; API route:&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;getXataClient&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;@utils/xata&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;xata&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getXataClient&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;handler&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;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&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;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;price&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;imgUrl&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&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="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;xata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Products&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;price&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;img&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;imgUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
      &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;end&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;handler&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It takes the &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;price&lt;/code&gt;, and URL of the uploaded image and passes them as arguments to Xata’s &lt;code&gt;create&lt;/code&gt; method to add a new product to the &lt;code&gt;Products&lt;/code&gt; db.&lt;/p&gt;

&lt;p&gt;The code for the &lt;code&gt;update-product.js&lt;/code&gt; API route:&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;getXataClient&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;@utils/xata&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;xata&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getXataClient&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;handler&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;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&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;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;price&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&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="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;xata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Products&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&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="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;price&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
      &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;end&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;handler&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It takes the &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;price&lt;/code&gt;, and &lt;code&gt;id&lt;/code&gt; of a specific product and passes them as arguments to Xata’s &lt;code&gt;update&lt;/code&gt; method to update the product’s information.&lt;/p&gt;

&lt;p&gt;The code for the &lt;code&gt;delete-product.js&lt;/code&gt; API route:&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;getXataClient&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;@utils/xata&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;xata&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getXataClient&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;handler&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;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&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;id&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&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="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;xata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Products&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&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="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;end&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;handler&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It takes the &lt;code&gt;id&lt;/code&gt; of a specific product and passes it as a parameter to Xata’s &lt;code&gt;delete&lt;/code&gt; method to delete the product from the &lt;code&gt;Products&lt;/code&gt; db.&lt;/p&gt;

&lt;p&gt;Having set up the API routes, let’s proceed with other parts of the application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fetching and Displaying the Products in the Database
&lt;/h2&gt;

&lt;p&gt;We’ll start by fetching and displaying the products that are currently in the database. Update the &lt;code&gt;pages/shop.js&lt;/code&gt; file with the following 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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Box&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Flex&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="nx"&gt;VStack&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;@chakra-ui/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;ProductCard&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/ProductCard&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;getXataClient&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;utils/xata&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;ProductModal&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/ProductModal&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;AddProductForm&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/AddProductForm&lt;/span&gt;&lt;span class="dl"&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Shop&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Box&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;Flex&lt;/span&gt; &lt;span class="nx"&gt;justify&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;space-between&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;align&lt;/span&gt;&lt;span class="o"&gt;=&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;Heading&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;h1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;mb&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;5&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;Products&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Heading&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;ProductModal&lt;/span&gt; &lt;span class="nx"&gt;modalTitle&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Add product&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;modalBtnTitle&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Add Product&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;AddProductForm&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;/ProductModal&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;/Flex&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;VStack&lt;/span&gt; &lt;span class="nx"&gt;spacing&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2em&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;data&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;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;img&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;price&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;ProductCard&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&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="nx"&gt;img&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;img&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;price&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;price&lt;/span&gt;&lt;span class="p"&gt;}&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;id&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="p"&gt;))}&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/VStack&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;/Box&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;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getServerSideProps&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;xata&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getXataClient&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;xata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Products&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getAll&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="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we did the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Imported the &lt;code&gt;getXataClient&lt;/code&gt; utility and initialized a new instance&lt;/li&gt;
&lt;li&gt;Queried the &lt;code&gt;Products&lt;/code&gt; table and fetched all records with &lt;code&gt;getServerSideProps&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Passed the fetched data to the &lt;code&gt;ProductCard&lt;/code&gt; component to render&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Adding a Product
&lt;/h2&gt;

&lt;p&gt;Update the &lt;code&gt;components/AddProductForm.js&lt;/code&gt; file with the code below to set up the product addition functionality.&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;useState&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="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;Button&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Box&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;Input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;VStack&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useToast&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;@chakra-ui/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;ShowImageUploadWidget&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;@utils/upload&lt;/span&gt;&lt;span class="dl"&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;AddProductForm&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;imgUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setImgUrl&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;toast&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useToast&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;handleSubmit&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;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;preventDefault&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;formData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FormData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromEntries&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;formData&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;name&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;name&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;price&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;price&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/api/add-product&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;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&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;body&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;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;price&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;imgUrl&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reset&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nf"&gt;toast&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="p"&gt;};&lt;/span&gt;
      &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;form&lt;/span&gt; &lt;span class="nx"&gt;onSubmit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleSubmit&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="c1"&gt;//insert form fields here&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Button&lt;/span&gt;
            &lt;span class="nx"&gt;onClick&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="nc"&gt;ShowImageUploadWidget&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;setImgUrl&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;Upload&lt;/span&gt; &lt;span class="nx"&gt;Image&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Button&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;/form&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we did the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Created a &lt;code&gt;handleSubmit&lt;/code&gt; function that takes the form data and passes it to the &lt;code&gt;add-product&lt;/code&gt; route, which will handle pushing the form data to the &lt;code&gt;Products&lt;/code&gt; db&lt;/li&gt;
&lt;li&gt;Set up an &lt;code&gt;imgUrl&lt;/code&gt; state that will contain the URL of the product’s image users upload to Cloudinary&lt;/li&gt;
&lt;li&gt;Imported a &lt;code&gt;ShowImageUploadWidget&lt;/code&gt; function from the &lt;code&gt;utils&lt;/code&gt; directory&lt;/li&gt;
&lt;li&gt;Passed &lt;code&gt;ShowImageUploadWidget&lt;/code&gt; to the &lt;strong&gt;Upload Image&lt;/strong&gt; button’s &lt;code&gt;onClick&lt;/code&gt; event handler&lt;/li&gt;
&lt;li&gt;Used the &lt;code&gt;toast&lt;/code&gt; method to display a message upon successful form submission&lt;/li&gt;
&lt;li&gt;Passed &lt;code&gt;handleSubmit&lt;/code&gt; to the form’s &lt;code&gt;onSubmit&lt;/code&gt; event handler&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here’s the code for the &lt;code&gt;ShowImageUploadWidget&lt;/code&gt; function. Create a &lt;code&gt;utils/upload.js&lt;/code&gt; file and update it with the code. The product image upload is handled by &lt;a href="https://cloudinary.com/documentation/upload_widget/?utm_source=hackmamba&amp;amp;utm_campaign=hackmamba-hackathon&amp;amp;utm_medium=hackmamba-blog" rel="noopener noreferrer"&gt;Cloudinary’s Upload Widget&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ShowImageUploadWidget&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;setImgUrl&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cloudinary&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createUploadWidget&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;cloudName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;your-cloud-name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;uploadPreset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ml_default&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="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="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;error&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&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;event&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;success&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="nf"&gt;setImgUrl&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;info&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;thumbnail_url&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&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;ShowImageUploadWidget&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s breakdown the snippet above:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;ShowImageUploadWidget&lt;/code&gt; calls the &lt;code&gt;createUploadWidget&lt;/code&gt; that exists in the &lt;code&gt;cloudinary&lt;/code&gt; object&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;createUploadWidget&lt;/code&gt; takes in our &lt;code&gt;cloudname&lt;/code&gt; as part of its config&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ShowImageUploadWidget&lt;/code&gt; accepts the &lt;code&gt;setImgUrl&lt;/code&gt; function as an argument. If an avatar is uploaded successfully, the &lt;code&gt;imgUrl&lt;/code&gt; state will be updated with the URL of the avatar a user uploads&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We have to load the widget’s script in order for it to work. Next.js provides a &lt;code&gt;[Script](https://nextjs.org/docs/basic-features/script)&lt;/code&gt; &lt;a href="https://nextjs.org/docs/basic-features/script/?utm_source=hackmamba&amp;amp;utm_campaign=hackmamba-hackathon&amp;amp;utm_medium=hackmamba-blog" rel="noopener noreferrer"&gt;component&lt;/a&gt; that we can use to load third-party scripts in our application. &lt;/p&gt;

&lt;p&gt;Update the &lt;code&gt;_app.js&lt;/code&gt; file with the following 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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ChakraProvider&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;@chakra-ui/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;Wrapper&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;@layout/index&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;Script&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;next/script&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="nf"&gt;MyApp&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pageProps&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ChakraProvider&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;Script&lt;/span&gt;
            &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://upload-widget.cloudinary.com/global/all.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
            &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text/javascript&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
            &lt;span class="nx"&gt;strategy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;beforeInteractive&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;Wrapper&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;Component&lt;/span&gt; &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nx"&gt;pageProps&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;/Wrapper&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;/ChakraProvider&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;MyApp&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 imported the &lt;code&gt;Script&lt;/code&gt; component from Next.js and used it to load the widget’s script.&lt;/p&gt;

&lt;h2&gt;
  
  
  Updating a Product
&lt;/h2&gt;

&lt;p&gt;Update the &lt;code&gt;components/UpdateProductForm.js&lt;/code&gt; file with the code below to set up the product update functionality.&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;useRouter&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;next/router&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;Button&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;VStack&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useToast&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;@chakra-ui/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;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;UpdateProductForm&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;product&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;toast&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useToast&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;router&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRouter&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;handleSubmit&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;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;preventDefault&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;formData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FormData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromEntries&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;formData&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;name&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;name&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;price&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;price&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/api/update-product&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;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;PUT&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&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;body&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;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;product&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="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;price&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="nf"&gt;toast&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/shop&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="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;form&lt;/span&gt; &lt;span class="nx"&gt;onSubmit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleSubmit&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="c1"&gt;//insert form fields here&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/form&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we did the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Created a &lt;code&gt;handleSubmit&lt;/code&gt; function that takes the form data and passes it to the &lt;code&gt;update-product&lt;/code&gt;route, which will update the product’s data in the &lt;code&gt;Products&lt;/code&gt; db&lt;/li&gt;
&lt;li&gt;Used the &lt;code&gt;toast&lt;/code&gt; method to display a message upon successful form submission&lt;/li&gt;
&lt;li&gt;Redirected the user to the &lt;code&gt;/shop&lt;/code&gt; route after form submission&lt;/li&gt;
&lt;li&gt;Passed &lt;code&gt;handleSubmit&lt;/code&gt; to the form’s &lt;code&gt;onSubmit&lt;/code&gt; event handler&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Deleting a Product
&lt;/h2&gt;

&lt;p&gt;Update the &lt;code&gt;pages/product/[id].js&lt;/code&gt; file with the code below to set up the product deletion functionality.&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;Head&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;next/head&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;Image&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;next/image&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;useRouter&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;next/router&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;Box&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Flex&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="nx"&gt;HStack&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Text&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;@chakra-ui/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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getXataClient&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;@utils/xata&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;ProductModal&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/ProductModal&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;UpdateProductForm&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/UpdateProductForm&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;xata&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getXataClient&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Product&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;product&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;router&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRouter&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

      &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;deleteProduct&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="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/api/delete-product&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;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;DELETE&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&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;body&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;stringify&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="p"&gt;});&lt;/span&gt;
        &lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/shop&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="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Box&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="c1"&gt;//insert ui code here &lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Box&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;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getStaticProps&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;xata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Products&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
          &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;params&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="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;getMany&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="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;product&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="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="p"&gt;};&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;props&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="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getStaticPaths&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;products&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;xata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Products&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getAll&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="na"&gt;paths&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;products&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;product&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="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;product&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="p"&gt;})),&lt;/span&gt;
        &lt;span class="na"&gt;fallback&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we did the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Used &lt;code&gt;getStaticPaths&lt;/code&gt; and &lt;code&gt;getStaticProps&lt;/code&gt; to dynamically render the paths for each product&lt;/li&gt;
&lt;li&gt;Created a &lt;code&gt;deleteProduct&lt;/code&gt; function that takes in a product’s &lt;code&gt;id&lt;/code&gt; and passes it to the &lt;code&gt;delete-product&lt;/code&gt; route, which will delete the product from the db&lt;/li&gt;
&lt;li&gt;Redirected the user to the &lt;code&gt;/shop&lt;/code&gt; route after form submission&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With that, we have successfully set up the functionality for the application, and it is good to go.&lt;/p&gt;

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

&lt;p&gt;In this article, we learned how to create an ecommerce admin application with Xata and Cloudinary.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://cloudinary.com/documentation/product_gallery" rel="noopener noreferrer"&gt;Cloudinary&lt;/a&gt;&lt;a href="https://cloudinary.com/documentation/upload_widget/?utm_source=hackmamba&amp;amp;utm_campaign=hackmamba-hackathon&amp;amp;utm_medium=hackmamba-blog" rel="noopener noreferrer"&gt;'s Upload Widget Documentation&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nextjs.org/docs/basic-features/script/?utm_source=hackmamba&amp;amp;utm_campaign=hackmamba-hackathon&amp;amp;utm_medium=hackmamba-blog" rel="noopener noreferrer"&gt;Next Script Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://xata.io/docs/overview/?utm_source=hackmamba&amp;amp;utm_campaign=hackmamba-hackathon&amp;amp;utm_medium=hackmamba-blog" rel="noopener noreferrer"&gt;Xata’s Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>nextjs</category>
      <category>xata</category>
      <category>cloudinary</category>
      <category>ecommerce</category>
    </item>
    <item>
      <title>Build a Chat App with Cloudinary and Xata</title>
      <dc:creator>nefejames</dc:creator>
      <pubDate>Wed, 23 Nov 2022 09:13:54 +0000</pubDate>
      <link>https://forem.com/hackmamba/build-a-chat-app-with-cloudinary-and-xata-30o7</link>
      <guid>https://forem.com/hackmamba/build-a-chat-app-with-cloudinary-and-xata-30o7</guid>
      <description>&lt;p&gt;One common thing with platforms like WhatsApp, Telegram, Twitter, and Instagram is that they all offer great chat functionality via their mobile and web applications. The ability to communicate swiftly with people across the globe has never been more important.&lt;/p&gt;

&lt;p&gt;In this article, we‘ll learn how to create a chat application with Next.js, Cloudinary's Upload widget, and Xata.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo and Source Code
&lt;/h2&gt;

&lt;p&gt;View the live demo via &lt;a href="https://hackmamba-xata-chat-app.vercel.app/?utm_source=hackmamba&amp;amp;utm_campaign=hackmamba-hackathon&amp;amp;utm_medium=hackmamba-blog" rel="noopener noreferrer"&gt;this link&lt;/a&gt; and access the source code on &lt;a href="https://github.com/nefejames/hackmamba-xata-chat-app/?utm_source=hackmamba&amp;amp;utm_campaign=hackmamba-hackathon&amp;amp;utm_medium=hackmamba-blog" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;To follow along with this article, we need to have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Knowledge of React and Next.js&lt;/li&gt;
&lt;li&gt;A &lt;a href="https://cloudinary.com/console/?utm_source=hackmamba&amp;amp;utm_campaign=hackmamba-hackathon&amp;amp;utm_medium=hackmamba-blog" rel="noopener noreferrer"&gt;Cloudinary account&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;A &lt;a href="https://app.xata.io/signin/?utm_source=hackmamba&amp;amp;utm_campaign=hackmamba-hackathon&amp;amp;utm_medium=hackmamba-blog" rel="noopener noreferrer"&gt;Xata account&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Understanding of Chakra UI is advantageous but not required&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What Is Xata?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://xata.io/?utm_source=hackmamba&amp;amp;utm_campaign=hackmamba-hackathon&amp;amp;utm_medium=hackmamba-blog" rel="noopener noreferrer"&gt;Xata&lt;/a&gt; is a serverless database built on top of PostgreSQL and Elasticsearch. It comes with useful integrations with popular frameworks and technologies like Next.js, Netlify, Nuxt.js, Vercel, Remix, and SvelteKit.&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://cloudinary.com/?utm_source=hackmamba&amp;amp;utm_campaign=hackmamba-hackathon&amp;amp;utm_medium=hackmamba-blog" rel="noopener noreferrer"&gt;Cloudinary&lt;/a&gt; is a cloud-based and end-to-end platform with tools and functionalities for storing, processing, editing, managing, delivering, and transforming media assets.&lt;/p&gt;

&lt;h2&gt;
  
  
  What We Will Create
&lt;/h2&gt;

&lt;p&gt;The screenshot below shows the application we will create. &lt;br&gt;
Users can fill in their name, provide a message and upload their avatar through the form on the right. Upon clicking the &lt;strong&gt;Send&lt;/strong&gt; button, the data gets saved to Xata’s database. We fetch the chats from the database and display them on the left side of the application. &lt;br&gt;
The avatar image upload is handled by Cloudinary’s Upload Widget.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fg2nbs42xt18y8k75a87y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fg2nbs42xt18y8k75a87y.png" alt="the chat app we will create" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;Download, clone, or fork &lt;a href="https://github.com/nefejames/hackmamba-xata-chat-app-ui/?utm_source=hackmamba&amp;amp;utm_campaign=hackmamba-hackathon&amp;amp;utm_medium=hackmamba-blog" rel="noopener noreferrer"&gt;this starter template&lt;/a&gt; that contains the UI for the chat app.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    npx create-next-app xata-cloudinary-chat-app -e https://github.com/nefejames/hackmamba-xata-chat-app-ui
    or
    yarn create next-app xata-cloudinary-chat-app -e https://github.com/nefejames/hackmamba-xata-chat-app-ui
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, navigate to the project directory, and run the command below to install Chakra UI, Next.js, Xata’s SDK, and every other necessary dependency, then run the application.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    npm i
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The starter template consists of the following files:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;components/ChatContainer.js&lt;/code&gt;: the container that holds the chats &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;components/ChatInput.js&lt;/code&gt;: where users can input and submit new chats&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;components/ChatProfile.js&lt;/code&gt;: holds each user’s name, avatar, and chat message&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;layout/index.js&lt;/code&gt;: the layout for the application&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;utils&lt;/code&gt;: will hold the Xata instance and avatar upload logic, which we will set up later&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Setting up the Xata Database
&lt;/h2&gt;

&lt;p&gt;We start by creating a new database called &lt;strong&gt;chat-app&lt;/strong&gt; on our Xata account.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fkw06i8b6dovsbkjcd3lu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fkw06i8b6dovsbkjcd3lu.png" alt="creating a new database in Xata" width="800" height="352"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, create a &lt;code&gt;messages&lt;/code&gt; table that will contain the records of the chat messages that users submit. Each record will have &lt;code&gt;message&lt;/code&gt;, &lt;code&gt;author&lt;/code&gt;, &lt;code&gt;img&lt;/code&gt;, and &lt;code&gt;id&lt;/code&gt; properties; the &lt;code&gt;id&lt;/code&gt; is automatically generated by Xata.&lt;br&gt;
We got the images from the media uploads in our Cloudinary account.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fm9mtomtjsnot6pa66t7s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fm9mtomtjsnot6pa66t7s.png" alt="creating the messages records" width="800" height="316"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The database schema is ready, so let’s set up the Xata instance next, and integrate it into the application. &lt;/p&gt;
&lt;h2&gt;
  
  
  Setting up the Xata Instance
&lt;/h2&gt;

&lt;p&gt;Run the command below to install the CLI globally.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    npm install @xata.io/cli -g
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, run &lt;code&gt;xata auth login&lt;/code&gt;, which will prompt you to Create a new API key in the browser or use an existing one; we’ll go with the first option.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F3zwmmfw2qrf057ea8rlm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F3zwmmfw2qrf057ea8rlm.png" alt="login to create CLI API key" width="800" height="285"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once in the browser, give the API a name and click the &lt;strong&gt;Create API key&lt;/strong&gt; button.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fuz17dsiieq61jq2b3tc8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fuz17dsiieq61jq2b3tc8.png" alt="creating a Xata API ley" width="800" height="284"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Back on the dashboard, click on the &lt;strong&gt;Get Code Snippet&lt;/strong&gt; button at the top right corner and copy the second command. We will use it to initialize the project locally with the aid of the CLI.&lt;/p&gt;

&lt;p&gt;Run the command in the terminal and choose from the configuration options. The screenshot below shows the configurations for this application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fp10ww905uve046h0z4hm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fp10ww905uve046h0z4hm.png" alt="xata cli config" width="800" height="216"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The CLI will automatically create a &lt;code&gt;xata.js&lt;/code&gt; file that contains the &lt;code&gt;XataClient&lt;/code&gt; instance we need; let’s move on to the coding aspects of the application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fetching the Messages in the Database
&lt;/h2&gt;

&lt;p&gt;We’ll start by fetching the messages that already exist in the database. Update the &lt;code&gt;index.js&lt;/code&gt; file with the following 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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Box&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Flex&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="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@chakra-ui/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;ChatContainer&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/ChatContainer&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;ChatInput&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/ChatInput&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;getXataClient&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;@utils/xata&lt;/span&gt;&lt;span class="dl"&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Home&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="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="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Heading&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;h1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;mb&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;5&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;Xata&lt;/span&gt; &lt;span class="nx"&gt;Chat&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Heading&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;Flex&lt;/span&gt; &lt;span class="nx"&gt;flexDir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;column&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;row&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt; &lt;span class="nx"&gt;justifyContent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;space-between&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;ChatContainer&lt;/span&gt; &lt;span class="nx"&gt;chats&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="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;Box&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;ChatInput&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;/Box&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;/Flex&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="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getServerSideProps&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;xata&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getXataClient&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;xata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getAll&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="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we did the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Imported the &lt;code&gt;getXataClient&lt;/code&gt; utility and initialized a new instance&lt;/li&gt;
&lt;li&gt;Queried the &lt;code&gt;messages&lt;/code&gt; table and fetched all records with &lt;code&gt;getServerSideProps&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Passed the fetched data to the &lt;code&gt;ChatContainer&lt;/code&gt; component through props&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Displaying the Messages in the ChatContainer Component
&lt;/h2&gt;

&lt;p&gt;Here, we then loop through the data and display the individual messages in the UI.&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;Box&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;VStack&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;@chakra-ui/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;ChatProfile&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;./ChatProfile&lt;/span&gt;&lt;span class="dl"&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ChatContainer&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;chats&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Box&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;VStack&lt;/span&gt; &lt;span class="nx"&gt;spacing&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;chats&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;chat&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;ChatProfile&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;chat&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="nx"&gt;author&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;author&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="nx"&gt;img&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;img&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
              &lt;span class="sr"&gt;/&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;/VStack&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;/Box&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Setting up the Avatar Upload Functionality in the ChatInput Component
&lt;/h2&gt;

&lt;p&gt;When a user clicks on the &lt;strong&gt;Upload Avatar&lt;/strong&gt; button, &lt;a href="https://cloudinary.com/documentation/upload_widget/?utm_source=hackmamba&amp;amp;utm_campaign=hackmamba-hackathon&amp;amp;utm_medium=hackmamba-blog" rel="noopener noreferrer"&gt;Cloudinary’s Upload Widget&lt;/a&gt; will open, enabling the user to upload a picture; let’s set it up. Update the &lt;code&gt;ChatInput.js&lt;/code&gt; file with the following 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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&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="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;Box&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Flex&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;@chakra-ui/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;ShowImageUploadWidget&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;@utils/upload&lt;/span&gt;&lt;span class="dl"&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ChatInput&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;imgUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setImgUrl&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&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;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;Box&lt;/span&gt; &lt;span class="nx"&gt;w&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;full&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;400px&lt;/span&gt;&lt;span class="dl"&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;form&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;Flex&lt;/span&gt; &lt;span class="nx"&gt;flexDir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;column&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;Input&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;author&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;placeholder&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Author&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;Input&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;newMessage&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;placeholder&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Message&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;Button&lt;/span&gt;
                &lt;span class="nx"&gt;onClick&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="nc"&gt;ShowImageUploadWidget&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;setImgUrl&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;Upload&lt;/span&gt; &lt;span class="nx"&gt;Avatar&lt;/span&gt;
              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Button&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;Button&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;submit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Send&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Button&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;/Flex&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;/form&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;/Box&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we did the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set up an &lt;code&gt;imgUrl&lt;/code&gt; state that will contain the URL of the avatar users upload to Cloudinary&lt;/li&gt;
&lt;li&gt;Imported a &lt;code&gt;ShowImageUploadWidget&lt;/code&gt; function from the &lt;code&gt;utils&lt;/code&gt; directory&lt;/li&gt;
&lt;li&gt;Passed &lt;code&gt;ShowImageUploadWidget&lt;/code&gt; to the &lt;strong&gt;Upload Avatar&lt;/strong&gt; button’s &lt;code&gt;onClick&lt;/code&gt; event handler&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code&gt;ShowImageUploadWidget&lt;/code&gt; function is responsible for the upload functionality. Create a &lt;code&gt;upload.js&lt;/code&gt; file and paste the following code to set up &lt;code&gt;ShowImageUploadWidget&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ShowImageUploadWidget&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;setImgUrl&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cloudinary&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createUploadWidget&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;cloudName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;your-cloud-name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;uploadPreset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ml_default&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="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="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;error&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&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;event&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;success&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="nf"&gt;setImgUrl&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;info&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;thumbnail_url&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&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;ShowImageUploadWidget&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
JavaScript&lt;/p&gt;

&lt;p&gt;Let’s breakdown the snippet above:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;ShowImageUploadWidget&lt;/code&gt; calls the &lt;code&gt;createUploadWidget&lt;/code&gt; that exists in the &lt;code&gt;cloudinary&lt;/code&gt; object&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;createUploadWidget&lt;/code&gt; takes in our &lt;code&gt;cloudname&lt;/code&gt; as part of its config&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ShowImageUploadWidget&lt;/code&gt; accepts the &lt;code&gt;setImgUrl&lt;/code&gt; function as an argument. If an avatar is uploaded successfully, the &lt;code&gt;imgUrl&lt;/code&gt; state will be updated with the URL of the avatar a user uploads&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We have to load the widget’s script in order for it to work. Next.js provides a &lt;code&gt;[Script](https://nextjs.org/docs/basic-features/script)&lt;/code&gt; &lt;a href="https://nextjs.org/docs/basic-features/script/?utm_source=hackmamba&amp;amp;utm_campaign=hackmamba-hackathon&amp;amp;utm_medium=hackmamba-blog" rel="noopener noreferrer"&gt;component&lt;/a&gt; that we can use to load third-party scripts in our application. &lt;/p&gt;

&lt;p&gt;Update the &lt;code&gt;_app.js&lt;/code&gt; file with the following 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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ChakraProvider&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;@chakra-ui/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;Wrapper&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;@layout/index&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;Script&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;next/script&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="nf"&gt;MyApp&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pageProps&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ChakraProvider&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;Script&lt;/span&gt;
            &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://upload-widget.cloudinary.com/global/all.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
            &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text/javascript&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
            &lt;span class="nx"&gt;strategy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;beforeInteractive&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;Wrapper&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;Component&lt;/span&gt; &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nx"&gt;pageProps&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;/Wrapper&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;/ChakraProvider&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;MyApp&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 imported the &lt;code&gt;Script&lt;/code&gt; component from Next.js and used it to load the widget’s script.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up the Form Submission Functionality in the ChatInput Component
&lt;/h2&gt;

&lt;p&gt;The form submission functionality is the last thing we need to set up. Update the &lt;code&gt;ChatInput&lt;/code&gt; component with the following 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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&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="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;Box&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Flex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useToast&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;@chakra-ui/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;ShowImageUploadWidget&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;@utils/upload&lt;/span&gt;&lt;span class="dl"&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ChatInput&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;toast&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useToast&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;imgUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setImgUrl&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&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;handleSubmit&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;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;preventDefault&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;formData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FormData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromEntries&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;formData&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;author&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;author&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;newMessage&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;newMessage&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/api/add-message&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;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&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;body&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;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="nx"&gt;author&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nx"&gt;newMessage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nx"&gt;imgUrl&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;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reset&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nf"&gt;toast&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Message created.&lt;/span&gt;&lt;span class="dl"&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Message sent to chat db.&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="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;Box&lt;/span&gt; &lt;span class="nx"&gt;w&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;full&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;400px&lt;/span&gt;&lt;span class="dl"&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;form&lt;/span&gt; &lt;span class="nx"&gt;onSubmit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleSubmit&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;Flex&lt;/span&gt; &lt;span class="nx"&gt;flexDir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;column&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;Input&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;author&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;placeholder&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Author&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;Input&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;newMessage&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;placeholder&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Message&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;Button&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="nx"&gt;Upload&lt;/span&gt; &lt;span class="nx"&gt;Avatar&lt;/span&gt;
              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Button&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;Button&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;submit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Send&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Button&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;/Flex&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;/form&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;/Box&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we did the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Created a &lt;code&gt;handleSubmit&lt;/code&gt; function that takes the form data and passes it on the &lt;code&gt;add-messages&lt;/code&gt; route. The &lt;code&gt;add-messages&lt;/code&gt; will handle pushing the form data to the Xata database; we will set up the route next&lt;/li&gt;
&lt;li&gt;Used the &lt;code&gt;toast&lt;/code&gt; method to display a message upon successful form submission&lt;/li&gt;
&lt;li&gt;Passed &lt;code&gt;handleSubmit&lt;/code&gt; to the form’s &lt;code&gt;onSubmit&lt;/code&gt; event handler&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For the API route, create a &lt;code&gt;api/add-message.js&lt;/code&gt; file and paste the following 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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getXataClient&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;@utils/xata&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;xata&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getXataClient&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;handler&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;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&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;author&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;newMessage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;imgUrl&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&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="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;xata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;author&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;author&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;newMessage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;img&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;imgUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
      &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;end&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;handler&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 did the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Imported the &lt;code&gt;getXataClient&lt;/code&gt; utility and initialized a new instance&lt;/li&gt;
&lt;li&gt;Accessed the &lt;code&gt;author&lt;/code&gt;, &lt;code&gt;newMessage&lt;/code&gt;, and &lt;code&gt;imgUrl&lt;/code&gt; from the request’s body&lt;/li&gt;
&lt;li&gt;Saved the new chat data to the &lt;code&gt;messages&lt;/code&gt; table on Xata&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;With that, we have successfully created a chat application with Cloudinary and Xata. The purpose of this simple is to give a brief overview of the features of these awesome technologies. We can take the project to the next step by validating the form fields during submission and adding user authentication and real-time functionality to the application.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://cloudinary.com/documentation/product_gallery" rel="noopener noreferrer"&gt;Cloudinary&lt;/a&gt;&lt;a href="https://cloudinary.com/documentation/upload_widget/?utm_source=hackmamba&amp;amp;utm_campaign=hackmamba-hackathon&amp;amp;utm_medium=hackmamba-blog" rel="noopener noreferrer"&gt;'s Upload Widget Documentation&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nextjs.org/docs/basic-features/script/?utm_source=hackmamba&amp;amp;utm_campaign=hackmamba-hackathon&amp;amp;utm_medium=hackmamba-blog" rel="noopener noreferrer"&gt;Next Script Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://xata.io/docs/overview/?utm_source=hackmamba&amp;amp;utm_campaign=hackmamba-hackathon&amp;amp;utm_medium=hackmamba-blog" rel="noopener noreferrer"&gt;Xata’s Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>xata</category>
      <category>cloudinary</category>
      <category>nextjs</category>
      <category>chat</category>
    </item>
    <item>
      <title>How to Authenticate a Next.js app with Okta</title>
      <dc:creator>nefejames</dc:creator>
      <pubDate>Tue, 16 Aug 2022 11:07:08 +0000</pubDate>
      <link>https://forem.com/hackmamba/how-to-authenticate-a-nextjs-app-with-okta-4dgl</link>
      <guid>https://forem.com/hackmamba/how-to-authenticate-a-nextjs-app-with-okta-4dgl</guid>
      <description>&lt;p&gt;Ensuring that only authenticated users have access to specific parts of an application is an important aspect of web development.&lt;/p&gt;

&lt;p&gt;In this article, we will learn how to authenticate a Next.js application using Appwrite’s Okta OAuth2 provider.&lt;/p&gt;

&lt;p&gt;The source code is also available on &lt;a href="https://github.com/nefejames/hackmamba-okta-next-auth" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;To get the most out of this project, the following are required:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Basic understanding of React and Next.js&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Docker &lt;a href="https://docs.docker.com/get-docker/" rel="noopener noreferrer"&gt;installation&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;An Appwrite instance; check out this &lt;a href="https://dev.to/hackmamba/create-a-local-appwrite-instance-in-3-steps-19n9?utm_source=hackmamba&amp;amp;utm_medium=hackmamba"&gt;article&lt;/a&gt; on how to set up an instance&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;An Okta developer account (sign up &lt;a href="https://developer.okta.com/signup/" rel="noopener noreferrer"&gt;here&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Create a Next.js project by running the command below in our terminal:&lt;/p&gt;

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

npx create-next-app okta-auth-app


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

&lt;/div&gt;

&lt;p&gt;Next, navigate into the project directory.&lt;/p&gt;

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

&lt;span class="nb"&gt;cd &lt;/span&gt;okta-auth-app


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

&lt;/div&gt;

&lt;p&gt;Then, run the command below to start the application:&lt;/p&gt;

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

 npm run dev


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

&lt;/div&gt;
&lt;h2&gt;
  
  
  Installing Appwrite
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://appwrite.io/?utm_source=hackmamba&amp;amp;utm_medium=hackmamba-blog" rel="noopener noreferrer"&gt;Appwrite&lt;/a&gt; is an open-source, end-to-end development platform that allows developers to build applications faster. Run the command below to install it:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

npm i appwrite


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

&lt;/div&gt;
&lt;h2&gt;
  
  
  Creating a New Appwrite Project
&lt;/h2&gt;

&lt;p&gt;To create a new project, start up the Appwrite instance on your machine and navigate to the specified hostname and port &lt;a href="http://localhost:80" rel="noopener noreferrer"&gt;http://localhost:80&lt;/a&gt;. Next, we need to log in to our account or create an account if we don’t have one.&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%2Fpaper-attachments.dropbox.com%2Fs_1638054D4FB2873BD3F938D25C75E763BFF13000BF29E067143C7C912818FACD_1655881360241_4-UbCF0g.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%2Fpaper-attachments.dropbox.com%2Fs_1638054D4FB2873BD3F938D25C75E763BFF13000BF29E067143C7C912818FACD_1655881360241_4-UbCF0g.png" alt="Signup/login page"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On the console, click the &lt;strong&gt;Create Project&lt;/strong&gt; button, give the project a name, and then click &lt;strong&gt;Create&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%2Fpaper-attachments.dropbox.com%2Fs_9C6F95223612512F2BFCBBAA719BAF62E5E51518F8EC1B3A16905A2D91336244_1650159125946_Screenshot%2B2022-04-17%2Bat%2B02.28.39.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%2Fpaper-attachments.dropbox.com%2Fs_9C6F95223612512F2BFCBBAA719BAF62E5E51518F8EC1B3A16905A2D91336244_1650159125946_Screenshot%2B2022-04-17%2Bat%2B02.28.39.png" alt="Create project"&gt;&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%2Fpaper-attachments.dropbox.com%2Fs_BDB4B2E9DEBC947CF21789BC4224D1B5D1E6999B18844A1ABC22F2142E2E2A61_1653953612228_Screenshot%2B2022-05-30%2Bat%2B15.00.51.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%2Fpaper-attachments.dropbox.com%2Fs_BDB4B2E9DEBC947CF21789BC4224D1B5D1E6999B18844A1ABC22F2142E2E2A61_1653953612228_Screenshot%2B2022-05-30%2Bat%2B15.00.51.png" alt="Enter project name"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The project dashboard will appear on the console. Next, click on the &lt;strong&gt;Settings&lt;/strong&gt; tab and copy the &lt;strong&gt;Project ID&lt;/strong&gt; and &lt;strong&gt;API Endpoint&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%2Fpaper-attachments.dropbox.com%2Fs_1638054D4FB2873BD3F938D25C75E763BFF13000BF29E067143C7C912818FACD_1655881587894_project%2Bappwrite.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%2Fpaper-attachments.dropbox.com%2Fs_1638054D4FB2873BD3F938D25C75E763BFF13000BF29E067143C7C912818FACD_1655881587894_project%2Bappwrite.png" alt="Appwrite Project ID and API Endpoint"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Creating an Appwrite Instance in the Next.js App
&lt;/h2&gt;

&lt;p&gt;Create a &lt;code&gt;utils.js&lt;/code&gt; file in the root of the application and in there, paste the code below:&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;Appwrite&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;appwrite&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;appwrite&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Appwrite&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;appwrite&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setEndpoint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;http://localhost/v1&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="nf"&gt;setProject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;your-project-id&lt;/span&gt;&lt;span class="dl"&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;appwrite&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;We used the Appwrite &lt;strong&gt;Project ID&lt;/strong&gt; and &lt;strong&gt;API Endpoint&lt;/strong&gt; to set up the instance in our application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Activating Okta Auth Method on Appwrite
&lt;/h2&gt;

&lt;p&gt;Navigate to the &lt;strong&gt;Users&lt;/strong&gt; menu, select the &lt;strong&gt;Settings&lt;/strong&gt; tab, and enable the &lt;strong&gt;Okta&lt;/strong&gt; OAuth2 provider:&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%2Fpaper-attachments.dropbox.com%2Fs_1638054D4FB2873BD3F938D25C75E763BFF13000BF29E067143C7C912818FACD_1655882165929_appwrite%2BOauth%2Bproviders.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%2Fpaper-attachments.dropbox.com%2Fs_1638054D4FB2873BD3F938D25C75E763BFF13000BF29E067143C7C912818FACD_1655882165929_appwrite%2BOauth%2Bproviders.png" alt="Okta providers"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Upon enabling the Okta provider, we will be required to fill in the &lt;strong&gt;App ID&lt;/strong&gt; and &lt;strong&gt;App Secret&lt;/strong&gt;. We will fill them in shortly.&lt;/p&gt;

&lt;p&gt;Copy Appwrite’s &lt;strong&gt;callback URI&lt;/strong&gt; below, as we will need it to configure the Okta authentication later.&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%2Fpaper-attachments.dropbox.com%2Fs_1638054D4FB2873BD3F938D25C75E763BFF13000BF29E067143C7C912818FACD_1655927856388_Screenshot_20.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%2Fpaper-attachments.dropbox.com%2Fs_1638054D4FB2873BD3F938D25C75E763BFF13000BF29E067143C7C912818FACD_1655927856388_Screenshot_20.png" alt="Okta's OAuth settings"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up an Okta Application
&lt;/h2&gt;

&lt;p&gt;We need to set up a new integration on our Okta account. Go to the &lt;strong&gt;Applications&lt;/strong&gt; page on the sidebar menu and click the &lt;strong&gt;Create App Integration&lt;/strong&gt; button.&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%2Fpaper-attachments.dropbox.com%2Fs_1638054D4FB2873BD3F938D25C75E763BFF13000BF29E067143C7C912818FACD_1655882738295_Screenshot_11.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%2Fpaper-attachments.dropbox.com%2Fs_1638054D4FB2873BD3F938D25C75E763BFF13000BF29E067143C7C912818FACD_1655882738295_Screenshot_11.png" alt="Okta developer account page"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select &lt;strong&gt;OIDC - OpenID Connect&lt;/strong&gt; as the &lt;strong&gt;Sign-in method&lt;/strong&gt; and &lt;strong&gt;Web Application&lt;/strong&gt; as the &lt;strong&gt;Application type&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%2Fpaper-attachments.dropbox.com%2Fs_1638054D4FB2873BD3F938D25C75E763BFF13000BF29E067143C7C912818FACD_1655882782830_Screenshot_12.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%2Fpaper-attachments.dropbox.com%2Fs_1638054D4FB2873BD3F938D25C75E763BFF13000BF29E067143C7C912818FACD_1655882782830_Screenshot_12.png" alt="Creating a new Okta app integration"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We need to configure the new app integration to work with Appwrite. Add the &lt;strong&gt;callback URI&lt;/strong&gt; we copied earlier as one of the &lt;strong&gt;Sign-in redirect URIs&lt;/strong&gt;, then save the application.&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%2Fpaper-attachments.dropbox.com%2Fs_1638054D4FB2873BD3F938D25C75E763BFF13000BF29E067143C7C912818FACD_1655923982048_Screenshot_17.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%2Fpaper-attachments.dropbox.com%2Fs_1638054D4FB2873BD3F938D25C75E763BFF13000BF29E067143C7C912818FACD_1655923982048_Screenshot_17.png" alt="New app integration"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We also need to copy the &lt;strong&gt;Okta domain&lt;/strong&gt;, &lt;strong&gt;Client ID&lt;/strong&gt;, and &lt;strong&gt;Client Secret&lt;/strong&gt; and paste them into our Appwrite configuration. Then, click &lt;strong&gt;Update&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%2Fpaper-attachments.dropbox.com%2Fs_1638054D4FB2873BD3F938D25C75E763BFF13000BF29E067143C7C912818FACD_1655882954151_Screenshot_14.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%2Fpaper-attachments.dropbox.com%2Fs_1638054D4FB2873BD3F938D25C75E763BFF13000BF29E067143C7C912818FACD_1655882954151_Screenshot_14.png" alt="Okta Client ID and Secret"&gt;&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%2Fpaper-attachments.dropbox.com%2Fs_1638054D4FB2873BD3F938D25C75E763BFF13000BF29E067143C7C912818FACD_1655883031473_Screenshot_15.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%2Fpaper-attachments.dropbox.com%2Fs_1638054D4FB2873BD3F938D25C75E763BFF13000BF29E067143C7C912818FACD_1655883031473_Screenshot_15.png" alt="Update Okta provider on Appwrite"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Integrating Appwrite Authentication into Next.js
&lt;/h2&gt;

&lt;p&gt;The application will contain two pages; a page to log in and another page to show logged-in user details.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Creating the login page&lt;/strong&gt; Update the &lt;code&gt;index.js&lt;/code&gt; file inside the &lt;code&gt;pages&lt;/code&gt; folder with the snippet below:&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;Head&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;next/head&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;Button&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Center&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;@chakra-ui/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;appwrite&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;utils&lt;/span&gt;&lt;span class="dl"&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Home&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;loginWithOkta&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;appwrite&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createOAuth2Session&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;okta&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;http://localhost:3000/user&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;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;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;Center&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;Button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;loginWithOkta&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;Login&lt;/span&gt; &lt;span class="kd"&gt;with&lt;/span&gt; &lt;span class="nx"&gt;Okta&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Button&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;/Center&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Here, we did the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Imported the required dependencies&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Created a &lt;code&gt;loginWithOkta&lt;/code&gt; asynchronous function that uses the Appwrite dk we initialized earlier to authenticate using Okta as the provider and &lt;code&gt;http://localhost:3000/user&lt;/code&gt; as the URL it redirects to when the authentication is successful; we will create the user page in the next section&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Passed the &lt;code&gt;loginWithOkta&lt;/code&gt; function to the button’s &lt;code&gt;onClick&lt;/code&gt; handler&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Creating the User Page&lt;/strong&gt; &lt;br&gt;
Create a &lt;code&gt;user.js&lt;/code&gt; file in the &lt;code&gt;pages&lt;/code&gt; directory and update it with the snippet below:&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;Button&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Center&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Text&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="nx"&gt;Stack&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;@chakra-ui/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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useState&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="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;useRouter&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;next/router&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;appwrite&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;utils&lt;/span&gt;&lt;span class="dl"&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;User&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;loggedInUser&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setLoggedInUser&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&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;router&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRouter&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;getLoggedInUser&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="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;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;appwrite&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;appwrite&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&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="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setLoggedInUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&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="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="nf"&gt;getLoggedInUser&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;logOut&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;appwrite&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;deleteSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;current&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;logout successful&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="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="nx"&gt;loggedInUser&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;&lt;/span&gt;&lt;span class="nx"&gt;Center&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;Stack&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;Heading&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;You&lt;/span&gt; &lt;span class="nx"&gt;logged&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;successfully&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Heading&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;Text&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;loggedInUser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Text&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;Email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;loggedInUser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&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;Button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;logOut&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;mt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;20&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;Logout&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Button&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;/Stack&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;/Center&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="p"&gt;}&lt;/span&gt;


&lt;span class="s2"&gt;```javascript

Here, we did the following:

-   Imported the required dependencies

-   Created state and route variables to manage logged-in user sessions and route accordingly

-   Created a `&lt;/span&gt;&lt;span class="nx"&gt;getLoggedInUser&lt;/span&gt;&lt;span class="s2"&gt;` function to get the logged-in user session and re-route to the login page if the session is empty and also called the function upon page load using the `&lt;/span&gt;&lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="s2"&gt;` hook

-   Created a `&lt;/span&gt;&lt;span class="nx"&gt;logOut&lt;/span&gt;&lt;span class="s2"&gt;` function to log the user out and passed it to the button’s `&lt;/span&gt;&lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="s2"&gt;` handler

With that, we have successfully authenticated a Next.js app application with Okta.

![Demo](https://paper-attachments.dropbox.com/s_1638054D4FB2873BD3F938D25C75E763BFF13000BF29E067143C7C912818FACD_1656544770916_ezgif.com-gif-maker2.gif)

Conclusion
----------

This post discussed how to authenticate a Next.js application using Appwrite’s Okta OAuth2 provider.

Resources
---------

These resources might be helpful:

-   [Set up Appwrite instance locally](https://dev.to/hackmamba/create-a-local-appwrite-instance-in-3-steps-19n9?utm_source=hackmamba&amp;amp;utm_medium=hackmamba) 

-   [Appwrite OAuth2 documentation](https://appwrite.io/docs/client/account?sdk=web-default#accountCreateOAuth2Session)

-   [Appwrite - Getting Started for Web](https://appwrite.io/docs/getting-started-for-web)


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

&lt;/div&gt;

</description>
      <category>appwrite</category>
      <category>nextjs</category>
      <category>okta</category>
      <category>authentication</category>
    </item>
    <item>
      <title>Build an Ecommerce Store with Next.js, Auth0 and Cloudinary</title>
      <dc:creator>nefejames</dc:creator>
      <pubDate>Mon, 18 Oct 2021 08:14:51 +0000</pubDate>
      <link>https://forem.com/hackmamba/build-an-ecommerce-store-with-nextjs-auth0-and-cloudinary-dgo</link>
      <guid>https://forem.com/hackmamba/build-an-ecommerce-store-with-nextjs-auth0-and-cloudinary-dgo</guid>
      <description>&lt;p&gt;Multimedia content optimization is the process of delivering high-quality media files in the right dimension, size, and format without sacrificing quality. &lt;/p&gt;

&lt;p&gt;When poorly optimized, the images and videos in your websites can lead to a poor user experience, loss of traffic, and low SEO rankings. &lt;/p&gt;

&lt;p&gt;In this article, we will learn how Cloudinary enables us to serve fast-loading images and videos through their CDN. We will also learn to set up user authentication with Auth0 and create responsive components with Chakra UI. We will combine these technologies to develop an eCommerce application.  &lt;/p&gt;

&lt;p&gt;We completed the project demo in &lt;a href="https://codesandbox.io/s/broken-wood-4vb7o" rel="noopener noreferrer"&gt;a codesandbox&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;You can find the deployed version &lt;a href="https://hackmamba-project-19or6wbnq-nefejames.vercel.app/" rel="noopener noreferrer"&gt;here&lt;/a&gt; and the codebase in this &lt;a href="https://github.com/nefejames/hackmamba-project" rel="noopener noreferrer"&gt;Github repo&lt;/a&gt;.&lt;/p&gt;

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

&lt;p&gt;Having some knowledge of and experience with, React.js and Chakra UI are required to follow the steps in this article. We will use the images and videos hosted on &lt;a href="https://cloudinary.com/" rel="noopener noreferrer"&gt;Cloudinary&lt;/a&gt; so you will need a &lt;a href="https://cloudinary.com/users/register/free" rel="noopener noreferrer"&gt;Cloudinary account&lt;/a&gt;. &lt;a href="https://auth0.com/" rel="noopener noreferrer"&gt;Auth0&lt;/a&gt; will handle the user authentication through their &lt;a href="https://auth0.com/docs/login/universal-login" rel="noopener noreferrer"&gt;universal login&lt;/a&gt; service, so you must &lt;a href="https://auth0.com/signu%20p" rel="noopener noreferrer"&gt;create an account&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As I mentioned earlier, we will be using Next.js in this project, so we need to &lt;a href="https://nextjs.org/docs/api-reference/create-next-ap" rel="noopener noreferrer"&gt;scaffold a new Next.js application&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We will also use the following packages in the application:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/cloudinary/cloudinary-react" rel="noopener noreferrer"&gt;cloudinary-react&lt;/a&gt;’s Video component to display videos.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/auth0/nextjs-auth0" rel="noopener noreferrer"&gt;Auth0’s Next.js SDK&lt;/a&gt; to handle the user authentication.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/chakra-ui/chakra-ui" rel="noopener noreferrer"&gt;Chakra UI&lt;/a&gt; to create the user interface.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We install the required packages in our application using the CLI command:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i chakra-ui cloudinary-react auth0/nextjs-auth0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Creating the Homepage
&lt;/h2&gt;

&lt;p&gt;The homepage consists of a header and a hero section; the header consists of the logo and a login/sign-in button, and the hero consists of the website copy on the left and an image on the right.&lt;/p&gt;

&lt;p&gt;We can see the appearance of the homepage in the image below.&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%2Fpaper-attachments.dropbox.com%2Fs_D65A090A5542872AAE6A8DDDEE64FCB43060C51AA27CE7D7D1C131AFDB8E304B_1632582978011_homepage.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%2Fpaper-attachments.dropbox.com%2Fs_D65A090A5542872AAE6A8DDDEE64FCB43060C51AA27CE7D7D1C131AFDB8E304B_1632582978011_homepage.PNG" alt="PetShop Homepage"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s begin by creating the layout for the homepage.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    import { Box, Container } from "@chakra-ui/react";
    import HomeHeader from "@components/Headers/Home";

    export default function HomeLayout({ children }) {
      return (
        &amp;lt;Box&amp;gt;
          &amp;lt;Container maxW={"7xl"}&amp;gt;
            &amp;lt;HomeHeader /&amp;gt;

            {children}
          &amp;lt;/Container&amp;gt;
        &amp;lt;/Box&amp;gt;
      );
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the homepage layout, we create a component, &lt;code&gt;HomeLayout&lt;/code&gt;. &lt;code&gt;HomeLayout&lt;/code&gt; consists of a &lt;code&gt;HomeHeader&lt;/code&gt; component and the children we will pass into it later. &lt;code&gt;HomeLayout&lt;/code&gt; is where the hero section will sit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Creating the Homepage Header&lt;/strong&gt;&lt;br&gt;
Next, we create the homepage header.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    import NextLink from "next/link";
    import { Box, Flex, Button } from "@chakra-ui/react";
    import Logo from "@svgs/Logo";

    export default function HomeHeader() {
      return (
        &amp;lt;Box&amp;gt;
          &amp;lt;Flex&amp;gt;
            &amp;lt;NextLink href="/" rel="noopener noreferrer" target="_blank"&amp;gt;
              &amp;lt;a&amp;gt;
                &amp;lt;Logo /&amp;gt;
              &amp;lt;/a&amp;gt;
            &amp;lt;/NextLink&amp;gt;
          &amp;lt;/Flex&amp;gt;      
        &amp;lt;/Box&amp;gt;
      );
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;HomeHeader&lt;/code&gt; component is made up of the Logo. We will add a login button later in the article.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Creating the Hero Section&lt;/strong&gt;&lt;br&gt;
Now, we move on to the hero section.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    import { Stack, Flex, Box, Heading, Text, Image } from "@chakra-ui/react";
    import HomeLayout from "@layout/Home";

    export default function Home() {
      return (
        &amp;lt;HomeLayout&amp;gt;
          &amp;lt;Stack&amp;gt;
            &amp;lt;Stack flex={1} spacing={{ base: 5, md: 10 }}&amp;gt;
              &amp;lt;Heading lineHeight={1.1} fontWeight={600} fontSize={["3xl", "4xl", "6xl"]}
              &amp;gt;
                Get your perfect companion{" "}
                &amp;lt;Text as="span" color="blue.500"&amp;gt;
                  today!
                &amp;lt;/Text&amp;gt;
              &amp;lt;/Heading&amp;gt;
              &amp;lt;Text color="gray.200" fontSize={["lg"]}&amp;gt;
                Buyng a pet is a big decision, and we are here to help you through
                the process. It's time to add a new love to your family. Discover
                the right pet for you. It's time to find your new best friend.
              &amp;lt;/Text&amp;gt;
            &amp;lt;/Stack&amp;gt;
            &amp;lt;Flex&amp;gt;
              &amp;lt;Box&amp;gt;
                &amp;lt;Image alt="Hero Image" fit="cover" align="center" w="100%" h="100%"
                  src=" https://res.cloudinary.com/nefejames/image/upload/q_auto,f_auto,w_auto/v1632501665/Hackmamba/Images/hero.jpg"
                /&amp;gt;
              &amp;lt;/Box&amp;gt;
            &amp;lt;/Flex&amp;gt;
          &amp;lt;/Stack&amp;gt;
        &amp;lt;/HomeLayout&amp;gt;
      );
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The hero image is gotten from our Cloudinary media repository. Let’s breakdown the URL of the image:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;q_auto&lt;/code&gt;: produces a high quality image with a minimal the file size.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;f_auto&lt;/code&gt;: delivers the image in the best format supported by the browser.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;w_auto&lt;/code&gt;: serves images proportional to users’ device resolution and screen sizes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Creating the Dashboard
&lt;/h2&gt;

&lt;p&gt;The dashboard consists of a header, sidebar, and dashboard view that contains the products.&lt;br&gt;
The header consists of the logo and a button to toggle the sidebar.&lt;br&gt;
The sidebar consists of a link to illustrate how a dashboard looks in a full-scale application.&lt;/p&gt;

&lt;p&gt;Let’s start by creating the layout of the dashboard.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    import { useMediaQuery, Box, Stack } from "@chakra-ui/react";
    import Header from "@components/Headers/Dashboard/";
    import Page from "./Page";
    import { DesktopSidebar, MobileSidebar } from "@components/DashboardSidebar";

    export default function DashboardLayout({ children }) {
      const [isSmallScreen] = useMediaQuery("(max-width: 768px)");

      return (
        &amp;lt;Box w="full"&amp;gt;
          &amp;lt;Header /&amp;gt;
          &amp;lt;Box pos="relative" h="max-content"&amp;gt;
            &amp;lt;Stack direction="row" spacing={{ md: 5 }}&amp;gt;
              &amp;lt;DesktopSidebar /&amp;gt;
              {isSmallScreen &amp;amp;&amp;amp; &amp;lt;MobileSidebar /&amp;gt;}
              &amp;lt;Page&amp;gt;{children}&amp;lt;/Page&amp;gt;
            &amp;lt;/Stack&amp;gt;
          &amp;lt;/Box&amp;gt;
        &amp;lt;/Box&amp;gt;
      );
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The dashboard layout consists of two dashboards, a mobile dashboard, and another for desktops.&lt;br&gt;
We create a &lt;code&gt;DashboardLayout&lt;/code&gt; component and use Chakra’s &lt;code&gt;[useMediaQuery](https://chakra-ui.com/docs/hooks/use-media-query)&lt;/code&gt; hook to set up a &lt;code&gt;isSmallScreen&lt;/code&gt; boolean. We show the mobile sidebar when &lt;code&gt;isSmallScreen&lt;/code&gt; is true - when the max-width is 768px.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Dashboard Context and Interactivity Flow&lt;/strong&gt;&lt;br&gt;
Before we continue building the dashboard, we need to understand its flow. We want to add some interactivity to the dashboard to boost the user experience.&lt;/p&gt;

&lt;p&gt;We want to be able to toggle the width of the desktop sidebar. We also want the mobile sidebar to slide in and out when toggled.  &lt;/p&gt;

&lt;p&gt;A core aspect of this functionality is a sidebar context, which we will create. The value of the sidebar context is gotten from Chakra UI’s &lt;code&gt;[useDisclosure](https://chakra-ui.com/docs/hooks/use-disclosure)&lt;/code&gt; &lt;a href="https://chakra-ui.com/docs/hooks/use-disclosure" rel="noopener noreferrer"&gt;&lt;/a&gt;hook. &lt;code&gt;useDisclosure&lt;/code&gt; is a custom hook used to help handle common open, close, or toggle scenarios.&lt;/p&gt;

&lt;p&gt;When setting up the sidebar, we will create and export a &lt;code&gt;useSidebarAuth&lt;/code&gt; hook that consumes the sidebar context and makes its values accessible throughout the application.&lt;/p&gt;

&lt;p&gt;We will pass the &lt;code&gt;useSidebarAuth&lt;/code&gt; hook to a &lt;code&gt;SidebarToggleButton&lt;/code&gt; component which we will create later. &lt;code&gt;SidebarToggleButton&lt;/code&gt; will enable us to toggle the sidebar context’s &lt;code&gt;isOpen&lt;/code&gt; value when clicked. We will pass &lt;code&gt;SidebarToggleButton&lt;/code&gt; to the dashboard header later.&lt;br&gt;
Whenever a user clicks the &lt;code&gt;SidebarToggleButton&lt;/code&gt;, we alter the behavior of the desktop or mobile sidebars based on the current value of &lt;code&gt;isOpen&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The flow chart image below shows us how the sidebar context works with the dashboard components and how we will set up the interactivity.&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%2Fpaper-attachments.dropbox.com%2Fs_D65A090A5542872AAE6A8DDDEE64FCB43060C51AA27CE7D7D1C131AFDB8E304B_1632614220694_Untitled%2BDiagram.drawio1.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%2Fpaper-attachments.dropbox.com%2Fs_D65A090A5542872AAE6A8DDDEE64FCB43060C51AA27CE7D7D1C131AFDB8E304B_1632614220694_Untitled%2BDiagram.drawio1.png" alt="dashboard context and interactivity flow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Creating the Sidebar Context&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now that we understand the sidebar context and how it is used in the dashboard, let us set up the context.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    import { createContext, useContext } from "react";
    import { useDisclosure } from "@chakra-ui/react";

    const SidebarContext = createContext(null);
    export const useSidebarAuth = () =&amp;gt; useContext(SidebarContext);

    export default function SidebarContextProvider({ children }) {
      const sidebarState = useDisclosure();

      return (
        &amp;lt;SidebarContext.Provider value={sidebarState}&amp;gt;
          {children}
        &amp;lt;/SidebarContext.Provider&amp;gt;
      );
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As stated earlier, we use the &lt;code&gt;useDisclosure&lt;/code&gt; hook to set up the context and export a &lt;code&gt;useSidebarAuth&lt;/code&gt; hook that consumes the context.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Creating the Sidebar Toggle Button&lt;/strong&gt;&lt;br&gt;
The next thing we need to do is create the  &lt;code&gt;SidebarToggleButton&lt;/code&gt; component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    import { Icon, IconButton } from "@chakra-ui/react";
    import { CgClose, CgMenu } from "react-icons/cg";
    import { useSidebarAuth } from "@context/sidebarContext";

    export default function SidebarToggleButton() {
      const { onToggle, isOpen } = useSidebarAuth();
      const icon = isOpen ? CgClose : CgMenu;
      return (
        &amp;lt;IconButton
          size="sm"
          fontSize="lg"
          variant="ghost"
          onClick={onToggle}
          icon={&amp;lt;Icon as={icon} /&amp;gt;}
          aria-label="Toggle Actions"
          transition="all .4s ease-in-out"
        /&amp;gt;
      );
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As explained earlier, when &lt;code&gt;SidebarToggleButton&lt;/code&gt; is clicked, the &lt;code&gt;isOpen&lt;/code&gt; value of the context is toggled.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Creating the Dashboard Header&lt;/strong&gt;&lt;br&gt;
Next we set up the dashboard header.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    import NextLink from "next/link";
    import { Flex, Spacer, Stack, Button, Link } from "@chakra-ui/react";
    import SidebarToggleButton from "./components/SidebarToggleButton";
    import Logo from "@svgs/Logo";

    export default function DashboardHeader() {
      return (
        &amp;lt;Flex
          h="10vh"
          minH="70px"
          pos="sticky"
          top="0"
          zIndex="2"
        &amp;gt;
          &amp;lt;Stack direction="row" w="full" alignItems="center" spacing="8"&amp;gt;
            &amp;lt;NextLink href="/" rel="noopener noreferrer" target="_blank"&amp;gt;
              &amp;lt;a&amp;gt;
                &amp;lt;Logo /&amp;gt;
              &amp;lt;/a&amp;gt;
            &amp;lt;/NextLink&amp;gt;
            &amp;lt;SidebarToggleButton /&amp;gt;

          &amp;lt;/Stack&amp;gt;
        &amp;lt;/Flex&amp;gt;
      );
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As I explained with the flow chart, we add the &lt;code&gt;SidebarToggleButton&lt;/code&gt; component to the dashboard header.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Creating the Desktop Sidebar&lt;/strong&gt;&lt;br&gt;
The dashboard has two sidebars, one for mobile devices, and another for desktop devices. Let’s start with the desktop sidebar.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    import { useRouter } from "next/router";
    import { useSidebarAuth } from "@context/sidebarContext";

    export default function Sidebar() {
      const router = useRouter();

      return (
        &amp;lt;Stack
          minH="full"
          h="90vh"
          pos="sticky"
          top="10vh"
          display={["none", , "initial"]}
          transition="width .4s ease-in-out"
        &amp;gt;
          &amp;lt;NavLink
            active={router.pathname === "/"}
            name="Home"
            href="/"
            icon={IoHomeSharp}
          /&amp;gt;
        &amp;lt;/Stack&amp;gt;
      );
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We want the desktop sidebar to be hidden on mobile, so we set the display to none. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Creating the Mobile Sidebar&lt;/strong&gt;&lt;br&gt;
We make use of Chakra’s &lt;code&gt;[Drawer](https://chakra-ui.com/docs/overlay/drawe)&lt;/code&gt; component to set up the mobile sidebar.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    import { useEffect } from "react";
    import { useRouter } from "next/router";
    import {
      Drawer,
      DrawerCloseButton,
      DrawerContent,
      DrawerOverlay,
    } from "@chakra-ui/react";
    import { useSidebarAuth } from "@context/sidebarContext";
    import FullNavLink from "./FullNavLink";

    export default function MobileSidebar() {
      const router = useRouter();
      const { isOpen, onClose } = useSidebarAuth();

      useEffect(() =&amp;gt; {
        router.events.on("routeChangeComplete", onClose);
        return () =&amp;gt; {
          router.events.off("routeChangeComplete", onClose);
        };
      }, []);
      return (
        &amp;lt;Drawer isOpen={isOpen} onClose={onClose} placement="left"&amp;gt;
          &amp;lt;DrawerOverlay display={["initial", , "none"]}&amp;gt;
            &amp;lt;DrawerContent layerStyle="neutral" py={12} bg="gray.900"&amp;gt;
              &amp;lt;Stack spacing={2} fontSize="sm"&amp;gt;
                &amp;lt;DrawerCloseButton /&amp;gt;
                &amp;lt;FullNavLink
                  active={router.pathname === "/"}
                  name="Home"
                  href="/"
                  icon={IoHomeSharp}
                /&amp;gt;
              &amp;lt;/Stack&amp;gt;
            &amp;lt;/DrawerContent&amp;gt;
          &amp;lt;/DrawerOverlay&amp;gt;
        &amp;lt;/Drawer&amp;gt;
      );
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next.js provides a &lt;a href="https://nextjs.org/docs/api-reference/next/router#routerevents" rel="noopener noreferrer"&gt;router event&lt;/a&gt;, &lt;code&gt;routeChangeComplete&lt;/code&gt;, which we use to toggle the mobile sidebar when a link is clicked.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Dashboard View&lt;/strong&gt; &lt;br&gt;
Before we proceed, we need to break down the dashboard view. The dashboard view consists of the &lt;code&gt;DashboardLayout&lt;/code&gt; component we set up earlier, a grid of products in a &lt;code&gt;ProductCard&lt;/code&gt; component, and a &lt;code&gt;ModalProduct&lt;/code&gt; component.&lt;/p&gt;

&lt;p&gt;Let’s set up the dashboard view.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    import { useState } from "react";
    import { Box, SimpleGrid } from "@chakra-ui/react";
    import { motion } from "framer-motion";
    import ProductCard from "@components/ProductCard";
    import DashboardLayout from "@layout/Dashboard";
    import ModalProduct from "@components/ModalProduct";
    import data from "@root/data";
    const MotionSimpleGrid = motion(SimpleGrid);
    const MotionBox = motion(Box);

    export default function Dashboard() {
      const [modalData, setModalData] = useState(null);
      return (
        &amp;lt;DashboardLayout&amp;gt;
          &amp;lt;Box&amp;gt;
            &amp;lt;MotionSimpleGrid&amp;gt;
              {data.map((product) =&amp;gt; (
                &amp;lt;MotionBox variants={cardVariant} key={product.id}&amp;gt;
                  &amp;lt;ProductCard product={product} setModalData={setModalData} /&amp;gt;
                &amp;lt;/MotionBox&amp;gt;
              ))}
            &amp;lt;/MotionSimpleGrid&amp;gt;
            &amp;lt;ModalProduct
              isOpen={modalData ? true : false}
              onClose={() =&amp;gt; setModalData(null)}
              modalData={modalData}
            /&amp;gt;
          &amp;lt;/Box&amp;gt;
        &amp;lt;/DashboardLayout&amp;gt;
      );
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s breakdown the snippet above:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We define a &lt;code&gt;modalData&lt;/code&gt; state where the data of the clicked product will be stored. &lt;/li&gt;
&lt;li&gt;We pass &lt;code&gt;setModalData&lt;/code&gt; and the product data to the &lt;code&gt;ProductCard&lt;/code&gt; component. We will use this to update the &lt;code&gt;modalData&lt;/code&gt; state with the data from the current product being clicked.&lt;/li&gt;
&lt;li&gt;We pass an &lt;code&gt;isOpen&lt;/code&gt; boolean, an &lt;code&gt;onClose&lt;/code&gt; method and and the &lt;code&gt;modalData&lt;/code&gt; state to the &lt;code&gt;ModalProduct&lt;/code&gt; component. The value of &lt;code&gt;isOpen&lt;/code&gt; depends on the value of &lt;code&gt;modalData&lt;/code&gt;. If &lt;code&gt;modalData&lt;/code&gt; is null, then &lt;code&gt;isOpen&lt;/code&gt; is false. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When &lt;code&gt;ProductCard&lt;/code&gt; is clicked, it triggers &lt;code&gt;ModalProduct&lt;/code&gt; and causes &lt;code&gt;ModalProduct&lt;/code&gt; to pop up.&lt;/p&gt;

&lt;p&gt;Here’s a sample of the data we map through and pass to &lt;code&gt;ProductCard&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    const data = [
      {
        title: "First Pet",
        price: 250,
        img: "https://res.cloudinary.com/nefejames/image/upload/q_auto,f_auto,w_auto/Hackmamba/Images/pet1.jpg",
        video: "/Hackmamba/Videos/pet1",
      },
      {
        title: "Second Pet",
        price: 250,
        img: "https://res.cloudinary.com/nefejames/image/upload/q_auto,f_auto,w_auto/Hackmamba/Images/pet2.jpg",
        video: "/Hackmamba/Videos/pet2",
      },
      // other data objects below
    ]

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Creating the&lt;/strong&gt; &lt;code&gt;**ProductCard**&lt;/code&gt; &lt;strong&gt;and&lt;/strong&gt; &lt;code&gt;**ModalProduct**&lt;/code&gt; &lt;strong&gt;Component&lt;/strong&gt;&lt;br&gt;
Now that we understand how &lt;code&gt;ProductCard&lt;/code&gt; and &lt;code&gt;ModalProduct&lt;/code&gt; work, let’s create them.&lt;/p&gt;

&lt;p&gt;Let’s start with setting up &lt;code&gt;ProductCard&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    import Image from "next/image";
    import { Box, Flex } from "@chakra-ui/react";
    import { StarIcon } from "@chakra-ui/icons";

    export default function ProductCard({ product, setModalData }) {
      const { img, beds, baths, title, price } = product;
      const score = Math.floor(Math.random(5) * 5);
      const reviewCount = Math.floor(Math.random(50) * 50);

      return (
        &amp;lt;Flex&amp;gt;
          &amp;lt;Box onClick={() =&amp;gt; setModalData(product)}&amp;gt;
            &amp;lt;Box&amp;gt;
              &amp;lt;Image
                src={img}
                objectFit="cover"
                alt="picture of an animal"
                layout="fill"
                objectFit="cover"
              /&amp;gt;
            &amp;lt;/Box&amp;gt;

            &amp;lt;Box p="6"&amp;gt;
              &amp;lt;Box&amp;gt; {title} &amp;lt;/Box&amp;gt;
              &amp;lt;Box&amp;gt;${price}&amp;lt;/Box&amp;gt;

              &amp;lt;Box d="flex" mt="3" alignItems="center"&amp;gt;
                {Array(5)
                  .fill("")
                  .map((_, i) =&amp;gt; (
                    &amp;lt;StarIcon key={i} color={i &amp;lt; score ? "teal.500" : "gray.300"} /&amp;gt;
                  ))}
                &amp;lt;Box as="span" ml="2" color="gray.600" fontSize="sm"&amp;gt;
                  {reviewCount} reviews
                &amp;lt;/Box&amp;gt;
              &amp;lt;/Box&amp;gt;
            &amp;lt;/Box&amp;gt;
          &amp;lt;/Box&amp;gt;
        &amp;lt;/Flex&amp;gt;
      );
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As stated earlier, we pass &lt;code&gt;setModalData&lt;/code&gt; to &lt;code&gt;ProductCard&lt;/code&gt;. When &lt;code&gt;ProductCard&lt;/code&gt; is clicked, the &lt;code&gt;modalData&lt;/code&gt; state is updated with the data of the product card that was clicked.&lt;/p&gt;

&lt;p&gt;Next, let’s set up &lt;code&gt;ModalProduct&lt;/code&gt;. To do that we use Chakra UI’s &lt;a href="https://chakra-ui.com/docs/overlay/modal" rel="noopener noreferrer"&gt;Modal&lt;/a&gt; component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    import { Modal, ModalOverlay, ModalContent, ModalHeader, ModalFooter, ModalBody,
      ModalCloseButton, Button, useToast } from "@chakra-ui/react";
    import { Video } from "cloudinary-react";

    export default function ModalProduct({ isOpen, onClose, modalData }) {
      const { title, price, video } = modalData || {};
      const toast = useToast();

      const handleModalClose = () =&amp;gt; {
        toast({
          title: "Purchase successsful.",
          description: "One more happy pet.",
          status: "success",
          duration: 3000,
          isClosable: true,
        });
        setTimeout(() =&amp;gt; {
          onClose();
        }, 1000);
      };

      return (
        &amp;lt;Modal isOpen={isOpen} onClose={onClose} size="xl"&amp;gt;
          &amp;lt;ModalOverlay /&amp;gt;
          &amp;lt;ModalContent&amp;gt;
            &amp;lt;ModalCloseButton /&amp;gt;
            &amp;lt;ModalHeader&amp;gt;Pet Details&amp;lt;/ModalHeader&amp;gt;
            &amp;lt;ModalBody&amp;gt;
              &amp;lt;Box w="full" h="full"&amp;gt;
                &amp;lt;Video controls publicId={video} width={300} crop="scale" /&amp;gt;

                &amp;lt;Box pt="3"&amp;gt;
                  &amp;lt;Box&amp;gt; {title} &amp;lt;/Box&amp;gt;
                  ${price}
                &amp;lt;/Box&amp;gt;
              &amp;lt;/Box&amp;gt;
            &amp;lt;/ModalBody&amp;gt;
            &amp;lt;ModalFooter&amp;gt;
              &amp;lt;Button onClick={handleModalClose}&amp;gt;
                Purchase
              &amp;lt;/Button&amp;gt;
            &amp;lt;/ModalFooter&amp;gt;
          &amp;lt;/ModalContent&amp;gt;
        &amp;lt;/Modal&amp;gt;
      );
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Earlier, we passed &lt;code&gt;isOpen&lt;/code&gt;, &lt;code&gt;onClose&lt;/code&gt;, and &lt;code&gt;modalData&lt;/code&gt; to &lt;code&gt;ModalProduct&lt;/code&gt; from the dashboard view. In the snippet above, we access them through props. We use &lt;code&gt;isOpen&lt;/code&gt; and &lt;code&gt;onClose&lt;/code&gt; to set up the modal and pass the data from &lt;code&gt;modalData&lt;/code&gt; to the appropriate parts of &lt;code&gt;ModalProduct&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We also define a function, &lt;code&gt;handleModalClose&lt;/code&gt;, and pass it to the modal’s purchase button. The &lt;code&gt;handleModalClose&lt;/code&gt; function displays a &lt;a href="https://chakra-ui.com/docs/feedback/toast" rel="noopener noreferrer"&gt;success toast&lt;/a&gt; and closes the modal when it is called. &lt;/p&gt;

&lt;h2&gt;
  
  
  User Authentication
&lt;/h2&gt;

&lt;p&gt;As stated earlier, we will use Auth0 to handle the user authentication in this application. Auth0 has provided &lt;a href="https://auth0.com/blog/ultimate-guide-nextjs-authentication-auth0/" rel="noopener noreferrer"&gt;a guide&lt;/a&gt; on how to work with their Next.js SDK. &lt;br&gt;
The &lt;code&gt;useUser&lt;/code&gt; hook exports two objects, user and error, and an isLoading boolean. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;user&lt;/code&gt; contains information about the authenticated user.&lt;/li&gt;
&lt;li&gt;We use &lt;code&gt;isLoading&lt;/code&gt; to check if the SDK has completed loading.&lt;/li&gt;
&lt;li&gt;We use the &lt;code&gt;error&lt;/code&gt; object to check if there were any authentication errors. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We will use the logged-in user profile in the following parts of our application:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the &lt;code&gt;index.js&lt;/code&gt; page&lt;/li&gt;
&lt;li&gt;the homepage header&lt;/li&gt;
&lt;li&gt;the dashboard header&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The Index.js Page&lt;/strong&gt;&lt;br&gt;
When the user logs in from the homepage, we want to redirect them to the dashboard route. We set up a &lt;code&gt;useEffect&lt;/code&gt; and check if &lt;code&gt;user&lt;/code&gt; exists. If it does, we redirect the user to the app route.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    import { useEffect } from "react";
    import HomePage from "@views/Home";
    import { useUser } from "@auth0/nextjs-auth0";
    import { useRouter } from "next/router";

    export default function Home() {
      const { user } = useUser();
      const router = useRouter();

      useEffect(() =&amp;gt; {
        if (user) {
          router.push("/app");
        }
      }, [user, router]);

      return (
        &amp;lt;div&amp;gt;
          &amp;lt;Head&amp;gt;
            &amp;lt;title&amp;gt;Hackmamba PetShop&amp;lt;/title&amp;gt;
          &amp;lt;/Head&amp;gt;

          &amp;lt;HomePage /&amp;gt;
        &amp;lt;/div&amp;gt;
      );
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The Homepage Header&lt;/strong&gt;&lt;br&gt;
Here, we conditionally show the logout and login buttons. We show the login button if there is no user and the logout button if there is a logged-in user.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    import NextLink from "next/link";
    import { Box, Flex, Button } from "@chakra-ui/react";
    import Logo from "@svgs/Logo";
    import { useUser } from "@auth0/nextjs-auth0";

    export default function HomeHeader() {
      const { user, isLoading } = useUser();

      return (
        &amp;lt;Box&amp;gt;
          &amp;lt;Flex&amp;gt;
            &amp;lt;NextLink href="/" rel="noopener noreferrer" target="_blank"&amp;gt;
              &amp;lt;a&amp;gt;
                &amp;lt;Logo /&amp;gt;
              &amp;lt;/a&amp;gt;
            &amp;lt;/NextLink&amp;gt;

            {!isLoading &amp;amp;&amp;amp; !user &amp;amp;&amp;amp; (
              &amp;lt;NextLink href="/api/auth/login" passHref&amp;gt;
                &amp;lt;Button as="a" bg="blue.700" _hover={{ bg: "blue.900" }}&amp;gt;
                  Sign In/Log in
                &amp;lt;/Button&amp;gt;
              &amp;lt;/NextLink&amp;gt;
            )}

            {user &amp;amp;&amp;amp; (
              &amp;lt;NextLink href="/api/auth/logout" passHref&amp;gt;
                &amp;lt;Button as="a" bg="blue.700" _hover={{ bg: "blue.900" }}&amp;gt;
                  Logout
                &amp;lt;/Button&amp;gt;
              &amp;lt;/NextLink&amp;gt;
            )}
          &amp;lt;/Flex&amp;gt;
        &amp;lt;/Box&amp;gt;
      );
    }

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The Dashboard Header&lt;/strong&gt;&lt;br&gt;
Here, we show the logout button when a user is logged in.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    import NextLink from "next/link";
    import { Flex, Spacer, Stack, Button, Link } from "@chakra-ui/react";
    import SidebarToggleButton from "./components/SidebarToggleButton";
    import { useUser } from "@auth0/nextjs-auth0";
    import Logo from "@svgs/Logo";

    export default function DashboardHeader() {
      const { user } = useUser();

      return (
        &amp;lt;Flex&amp;gt;
          &amp;lt;Stack direction="row" w="full" alignItems="center" spacing="8"&amp;gt;
            &amp;lt;NextLink href="/" rel="noopener noreferrer" target="_blank"&amp;gt;
              &amp;lt;a&amp;gt;
                &amp;lt;Logo /&amp;gt;
              &amp;lt;/a&amp;gt;
            &amp;lt;/NextLink&amp;gt;
            &amp;lt;SidebarToggleButton /&amp;gt;

            &amp;lt;Spacer /&amp;gt;

            {user &amp;amp;&amp;amp; (
              &amp;lt;Link href="/api/auth/logout"&amp;gt;
                &amp;lt;Button bg="blue.700" _hover={{ bg: "blue.900" }}&amp;gt;Logout&amp;lt;/Button&amp;gt;
              &amp;lt;/Link&amp;gt;
            )}
          &amp;lt;/Stack&amp;gt;
        &amp;lt;/Flex&amp;gt;
      );
    }

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

&lt;/div&gt;



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

&lt;p&gt;We learned how to use Auth0, Next.js, Chakra UI, and Cloudinary to create an eCommerce application. We also learned how to add interactivity to our applications and make them responsive with Chakra UI’s &lt;code&gt;useDisclosure&lt;/code&gt; and &lt;code&gt;useMediaQuery&lt;/code&gt; hooks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Further Reading
&lt;/h2&gt;

&lt;p&gt;You can learn more about the technologies used from the links below.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cloudinary&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://cloudinary.com/documentation/react_video_manipulation" rel="noopener noreferrer"&gt;React video transformations&lt;/a&gt;&lt;br&gt;
&lt;a href="https://cloudinary.com/documentation/image_optimization" rel="noopener noreferrer"&gt;Image optimization&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/cloudinary/cloudinary-react" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;a href="https://github.com/cloudinary/cloudinary-react" rel="noopener noreferrer"&gt;cloudinary-react&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Auth0&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://auth0.com/docs/quickstart/webapp/nextjs/01-login" rel="noopener noreferrer"&gt;How to authenticate Next.js apps with Auth0&lt;/a&gt; &lt;br&gt;
&lt;a href="https://auth0.com/blog/ultimate-guide-nextjs-authentication-auth0/" rel="noopener noreferrer"&gt;The ultimate guide to Next.js authentication with Auth0&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Next.js&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://nextjs.org/docs/getting-started" rel="noopener noreferrer"&gt;Getting started with Next.js&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Content created for the &lt;a href="https://content.hackmamba.io/" rel="noopener noreferrer"&gt;Hackmamba&lt;/a&gt; Jamstack Content Hackathon&lt;/p&gt;

</description>
      <category>auth0</category>
      <category>cloudinary</category>
      <category>nextjs</category>
      <category>jamstack</category>
    </item>
  </channel>
</rss>
