<?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: Amrasakpare Lawrence</title>
    <description>The latest articles on Forem by Amrasakpare Lawrence (@devlawrence).</description>
    <link>https://forem.com/devlawrence</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%2F1044705%2F2cf11a26-12e4-4d20-850d-752b6c7b958f.jpg</url>
      <title>Forem: Amrasakpare Lawrence</title>
      <link>https://forem.com/devlawrence</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/devlawrence"/>
    <language>en</language>
    <item>
      <title>The Tech Stack I Use to Build and Ship Projects Fast as a Web Developer</title>
      <dc:creator>Amrasakpare Lawrence</dc:creator>
      <pubDate>Tue, 10 Feb 2026 11:00:00 +0000</pubDate>
      <link>https://forem.com/devlawrence/the-tech-stack-i-use-to-build-and-ship-projects-fast-as-a-web-developer-2gpm</link>
      <guid>https://forem.com/devlawrence/the-tech-stack-i-use-to-build-and-ship-projects-fast-as-a-web-developer-2gpm</guid>
      <description>&lt;p&gt;Over the past year, I have been building a lot of websites and web applications. Some for learning. Some for clients.&lt;/p&gt;

&lt;p&gt;Along the way, I slowly refined my tools and workflow until I landed on a stack that genuinely helps me move fast without feeling overwhelmed.&lt;/p&gt;

&lt;p&gt;In this article, I am going to break down the exact tools I use, why I chose each one, and how AI fits into my workflow.&lt;/p&gt;

&lt;p&gt;If you build client projects, side projects, or just want to ship faster, this should give you some useful ideas.&lt;/p&gt;

&lt;p&gt;Let us dive in.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Frontend Frameworks
&lt;/h2&gt;

&lt;p&gt;For web projects, I mainly use Next.js, Vite and Astro.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Next.js&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Next.js is what I use for full scale web applications.&lt;/p&gt;

&lt;p&gt;I reach for it when I need things like authentication, dashboards, server side logic, or complex user flows. The App Router makes it easy to organize large projects, and the overall developer experience feels very mature.&lt;/p&gt;

&lt;p&gt;It is especially useful when I am building products or internal tools where both frontend and backend logic need to live together cleanly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vite&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I use Vite when I want something lightweight and fast.&lt;/p&gt;

&lt;p&gt;For simple websites, small tools, or projects that do not need the full power of Next.js, Vite is perfect. It starts instantly, builds fast, and stays out of your way.&lt;/p&gt;

&lt;p&gt;Most of the time, this means pairing Vite with React for projects where I just want to focus on the UI without extra abstractions.&lt;/p&gt;

&lt;p&gt;If I am building a straightforward website or prototype and do not need server features, Vite is usually my first choice.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Astro&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I use Astro mostly for content focused websites.&lt;/p&gt;

&lt;p&gt;Examples include blogs, documentation sites, and marketing websites where performance is extremely important.&lt;/p&gt;

&lt;p&gt;Astro ships very little JavaScript to the browser, which leads to fast load times and great Lighthouse scores.&lt;/p&gt;

&lt;p&gt;For local businesses that care about SEO and speed, Astro is often the perfect choice.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Styling
&lt;/h2&gt;

&lt;p&gt;For styling, I use Tailwind CSS v4 together with shadcn.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tailwind CSS&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I used to write a lot of custom CSS (lol I still do most times), but Tailwind completely changed my workflow.&lt;/p&gt;

&lt;p&gt;Instead of switching between files and inventing class names, I can style directly in my components.&lt;/p&gt;

&lt;p&gt;Tailwind v4 also brings performance improvements and better developer experience, which makes it even more enjoyable to use.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;shadcn&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;shadcn is one of my favorite tools.&lt;/p&gt;

&lt;p&gt;It is not a traditional component library. Instead, you copy components into your project and fully own the code.&lt;/p&gt;

&lt;p&gt;That means:&lt;/p&gt;

&lt;p&gt;No vendor lock in&lt;/p&gt;

&lt;p&gt;Full control over styling&lt;/p&gt;

&lt;p&gt;Accessible components by default&lt;/p&gt;

&lt;p&gt;If I need a card, button, modal, or dropdown, I grab it from shadcn, paste it into my project, and customize it.&lt;/p&gt;

&lt;p&gt;Tailwind and shadcn together allow me to build full landing pages in hours instead of days.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Backend and Database
&lt;/h2&gt;

&lt;p&gt;For proper web applications, I use &lt;a href="https://convex.dev/referral/DEVLAW2008" rel="noopener noreferrer"&gt;Convex&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Convex&lt;/strong&gt; gives me:&lt;/p&gt;

&lt;p&gt;A database&lt;/p&gt;

&lt;p&gt;Backend functions&lt;/p&gt;

&lt;p&gt;Real time updates&lt;/p&gt;

&lt;p&gt;All in one platform.&lt;/p&gt;

&lt;p&gt;Instead of setting up a separate API server, I write JavaScript or TypeScript functions that directly talk to the database.&lt;/p&gt;

&lt;p&gt;This is great for things like:&lt;/p&gt;

&lt;p&gt;Booking systems&lt;/p&gt;

&lt;p&gt;Dashboards&lt;/p&gt;

&lt;p&gt;Real time features&lt;/p&gt;

&lt;p&gt;Development feels fast and simple, and Convex scales well as projects grow.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Content Management System&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I use Sanity CMS, but only when a project truly needs a CMS.&lt;/p&gt;

&lt;p&gt;Many business websites barely change content. In those cases, a CMS is unnecessary.&lt;/p&gt;

&lt;p&gt;But when clients want to edit:&lt;/p&gt;

&lt;p&gt;Blog posts&lt;/p&gt;

&lt;p&gt;Menus&lt;/p&gt;

&lt;p&gt;Team members&lt;/p&gt;

&lt;p&gt;Pages&lt;/p&gt;

&lt;p&gt;Sanity becomes extremely valuable.&lt;/p&gt;

&lt;p&gt;It is flexible, has a great editing experience, and integrates easily with both Next.js and Astro.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Authentication
&lt;/h2&gt;

&lt;p&gt;For authentication, I mostly use &lt;strong&gt;Clerk&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Clerk handles:&lt;/p&gt;

&lt;p&gt;Sign up and sign in&lt;/p&gt;

&lt;p&gt;User management&lt;/p&gt;

&lt;p&gt;Magic links&lt;/p&gt;

&lt;p&gt;Social logins&lt;/p&gt;

&lt;p&gt;The UI components look good out of the box, and setup is straightforward and you can build your own custom UI if you choose to.&lt;/p&gt;

&lt;p&gt;I have also been experimenting with Better Auth on some projects where I want more control, but Clerk is still my default because it saves a lot of time.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Mobile Development
&lt;/h2&gt;

&lt;p&gt;I am currently getting into mobile development using React Native with Expo.&lt;/p&gt;

&lt;p&gt;I am still learning, so I am not taking mobile client work yet.&lt;/p&gt;

&lt;p&gt;The biggest advantage is that I can reuse my React knowledge and build for both iOS and Android.&lt;/p&gt;

&lt;p&gt;If I already have a web app built with Next.js, I can share logic, validation, and sometimes even components.&lt;/p&gt;

&lt;p&gt;Expo removes a lot of the painful setup that usually scares people away from mobile development.&lt;/p&gt;

&lt;p&gt;If you are curious about mobile, Expo makes it a great place to start.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Monorepo Setup
&lt;/h2&gt;

&lt;p&gt;Recently, I started using &lt;strong&gt;Turborepo&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Turborepo allows me to keep multiple projects in a single repository.&lt;/p&gt;

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

&lt;p&gt;Web app&lt;/p&gt;

&lt;p&gt;Mobile app&lt;/p&gt;

&lt;p&gt;Shared UI components&lt;/p&gt;

&lt;p&gt;Shared utilities&lt;/p&gt;

&lt;p&gt;All living together.&lt;/p&gt;

&lt;p&gt;This means I can reuse code instead of copying and pasting between projects.&lt;/p&gt;

&lt;p&gt;It may sound complex, but once you set it up once, it actually simplifies things.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Payments
&lt;/h2&gt;

&lt;p&gt;For client projects in Nigeria, I use &lt;strong&gt;Paystack&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It works well for local businesses and has reasonable fees.&lt;/p&gt;

&lt;p&gt;For my own products and tutorials that I make, I use &lt;strong&gt;Stripe&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Stripe is globally supported and has excellent documentation.&lt;/p&gt;

&lt;p&gt;Both integrate nicely with Next.js.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Deployment
&lt;/h2&gt;

&lt;p&gt;My main deployment platform is &lt;strong&gt;Vercel&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Since Vercel builds Next.js, the experience feels seamless.&lt;/p&gt;

&lt;p&gt;Push to GitHub and your site is live.&lt;/p&gt;

&lt;p&gt;You also get:&lt;/p&gt;

&lt;p&gt;Automatic SSL&lt;/p&gt;

&lt;p&gt;Preview deployments&lt;/p&gt;

&lt;p&gt;Easy environment variables&lt;/p&gt;

&lt;p&gt;For Astro sites, I mostly use &lt;strong&gt;Netlify&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In rare cases where I need more backend control, I use &lt;strong&gt;Railway&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;But &lt;strong&gt;Vercel&lt;/strong&gt; handles most of my deployments.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Use AI
&lt;/h2&gt;

&lt;p&gt;I don't use AI powered IDEs like Cursor, at least not yet. I've only tried Cursor once or twice.&lt;/p&gt;

&lt;p&gt;I prefer writing my own code (or rather copy from a chat interface and pasting it into my code editor).&lt;/p&gt;

&lt;p&gt;I like understanding what I am building, and I learn better when I follow the approach I just mentioned.&lt;/p&gt;

&lt;p&gt;The main tools I use:&lt;/p&gt;

&lt;p&gt;t3.chat&lt;/p&gt;

&lt;p&gt;Claude Interface&lt;/p&gt;

&lt;p&gt;ChatGPT Interface&lt;/p&gt;

&lt;p&gt;The models I use most:&lt;/p&gt;

&lt;p&gt;Gemini 3 Pro&lt;/p&gt;

&lt;p&gt;Gpt 5 &lt;/p&gt;

&lt;p&gt;Claude Sonnet 4.5&lt;/p&gt;

&lt;p&gt;Clause Haiku 4.5&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;This stack allows me to go from idea to deployed project very quickly while still learning.&lt;/p&gt;

&lt;p&gt;AI plays a big role in my productivity, but it does not replace my thinking or my coding.&lt;/p&gt;

&lt;p&gt;I will be sharing more content where I build real projects using this exact stack, including websites, dashboards, booking systems, and mobile apps, later on.&lt;/p&gt;

&lt;p&gt;If you have questions about any part of the stack, feel free to ask.&lt;/p&gt;

&lt;p&gt;Happy building 🚀&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ai</category>
      <category>programming</category>
      <category>javascript</category>
    </item>
    <item>
      <title>How to Build a Portfolio Website the Right Way</title>
      <dc:creator>Amrasakpare Lawrence</dc:creator>
      <pubDate>Thu, 03 Apr 2025 23:00:00 +0000</pubDate>
      <link>https://forem.com/devlawrence/how-to-build-a-portfolio-website-the-right-way-2n87</link>
      <guid>https://forem.com/devlawrence/how-to-build-a-portfolio-website-the-right-way-2n87</guid>
      <description>&lt;p&gt;Creating a personal portfolio is a rite of passage for developers, but for many, it becomes an overwhelming task. You start with excitement, then suddenly, you're stuck overthinking design choices, switching tech stacks, or spending hours tweaking animations instead of showcasing your work. Sound familiar? I’ve been there too.&lt;/p&gt;

&lt;p&gt;That’s exactly why I built &lt;a href="https://portfoliokit.netlify.app/" rel="noopener noreferrer"&gt;&lt;strong&gt;PortfolioKit&lt;/strong&gt;&lt;/a&gt;— a tool to  help developers, designers, and freelancers skip the frustrating parts and get a professional, fully functional portfolio live in minutes.&lt;/p&gt;

&lt;h2&gt;
  
  
  😫 The Common Struggles of Building a Portfolio
&lt;/h2&gt;

&lt;p&gt;If you’ve ever tried to build a portfolio from scratch, you’ve likely faced some of these issues:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Overthinking Design&lt;/strong&gt; – Finding the perfect UI can be time-consuming. Should it be minimal, flashy, or somewhere in between?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tech Stack Dilemma&lt;/strong&gt; – React, Next.js, Astro, or plain HTML? Every option has trade-offs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Endless Customization&lt;/strong&gt; – Instead of launching, you spend hours fine-tuning fonts, colors, and layouts.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These challenges slow you down and distract from what truly matters—showcasing your work and landing opportunities.&lt;/p&gt;

&lt;h2&gt;
  
  
  ✨ How PortfolioKit Fixes These Problems
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://portfoliokit.netlify.app/" rel="noopener noreferrer"&gt;PortfolioKit&lt;/a&gt; is designed to remove the unnecessary headaches from building a portfolio so you can focus on what truly matters. Here’s how it helps 👇🏽&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1. Pre-Designed Templates That Look Great&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;No need to spend hours picking the right design. PortfolioKit provides clean, modern, and professional templates that you can customize to fit your style. Whether you're a developer, designer, or freelancer, there's a template that works for you.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;2. No Tech Stack Anxiety – Just Focus on Content&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;PortfolioKit is built using &lt;strong&gt;Astro and Sanity&lt;/strong&gt;, making it fast, flexible, and easy to update. You don’t need to worry about picking the “right” framework—everything is already optimized for performance and SEO.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;3. Easy Customization Without the Overwhelm&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Tweak colors, fonts, and layouts in minutes. PortfolioKit gives you enough flexibility to make your portfolio unique without spending endless hours adjusting minor details.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;4. Simple Deployment – Get Online Fast&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Forget complicated setups. With PortfolioKit, deployment is seamless, whether you choose &lt;strong&gt;Vercel or Netlify&lt;/strong&gt;. Your portfolio can go live with just a few clicks.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;5. Built for Growth – Add Projects, Blogs, and More&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;A good portfolio should evolve with your career. PortfolioKit makes it easy to update projects or even integrate a blog—all without rebuilding from scratch.&lt;/p&gt;

&lt;h2&gt;
  
  
  💡 Why I Created PortfolioKit
&lt;/h2&gt;

&lt;p&gt;When I built my first portfolio (which now uses PortfolioKit’s developer template), I went through all the struggles mentioned above. I wanted it to be perfect, so I kept redesigning, switching frameworks (frustrating 😅), and delaying my launch in search of perfection. It took far longer than necessary. Eventually, I realized &lt;strong&gt;a portfolio’s purpose is to showcase your skills, not to be a never-ending project itself&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That’s why I built PortfolioKit—to help developers avoid these distractions. With PortfolioKit, you can launch a sleek, professional portfolio in minutes, freeing you up to focus on what truly matters which is &lt;strong&gt;your work, your projects, and your career.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ⚡ Ready to Build Your Portfolio the Smart Way?
&lt;/h2&gt;

&lt;p&gt;If you’re tired of overcomplicating your portfolio, &lt;strong&gt;PortfolioKit makes it easy&lt;/strong&gt;. Get started today and get your portfolio online without the stress.&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://portfoliokit.netlify.app/" rel="noopener noreferrer"&gt;&lt;strong&gt;Check out PortfolioKit&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>portfolio</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>Here Are Some Productivity Tools That I Use Every Day</title>
      <dc:creator>Amrasakpare Lawrence</dc:creator>
      <pubDate>Thu, 30 Jan 2025 23:00:00 +0000</pubDate>
      <link>https://forem.com/devlawrence/here-are-some-productivity-tools-that-i-use-every-day-3p3b</link>
      <guid>https://forem.com/devlawrence/here-are-some-productivity-tools-that-i-use-every-day-3p3b</guid>
      <description>&lt;p&gt;Whatsup guys, so staying productive often feels like juggling multiple responsibilities at once. Between managing tasks, staying organized, and reducing distractions, the right tools can make a world of difference. &lt;br&gt;
In this article, I’ll show you some of my favorite productivity tools and Chrome extensions that helps in streamlining my workflow. let’s dive right in 😉.&lt;/p&gt;




&lt;h2&gt;
  
  
  General Productivity Tools
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1. Notion&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;First up is &lt;a href="https://affiliate.notion.so/azncqxyidix4" rel="noopener noreferrer"&gt;&lt;strong&gt;Notion&lt;/strong&gt;&lt;/a&gt;, which is what I use everyday. (Fun fact I’m even using it right now to write this article 😅). I use it to plan video ideas, track projects, blogs and manage my entire workflow. It does have a little learning curve to it though but the free templates they have will make your life so much easier. That being said let’s move on the next tool.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;2. Google Calendar and Google Tasks&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;When it comes to managing my schedule, &lt;a href="https://calendar.google.com/" rel="noopener noreferrer"&gt;&lt;strong&gt;Google Calendar&lt;/strong&gt;&lt;/a&gt; and &lt;strong&gt;Google Tasks&lt;/strong&gt; are indispensable. Google Calendar helps me block out dedicated time for work, meetings, and content creation. On the other hand, Google Tasks is perfect for jotting down quick to-dos and keeping track of small but essential tasks. The seamless syncing across devices ensures that I’m always on top of things, no matter where I am.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;3. Day One&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;For a more reflective and mindful approach to productivity, I use &lt;a href="https://dayoneapp.com/" rel="noopener noreferrer"&gt;&lt;strong&gt;Day One&lt;/strong&gt;&lt;/a&gt;. This journaling app helps me document my goals and progress. Taking a moment to write down my thoughts and reflect on my achievements keeps me grounded and motivated, especially when balancing multiple projects and life in general.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;4. Ueli&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;If you’re on Windows, &lt;a href="https://ueli.app/" rel="noopener noreferrer"&gt;&lt;strong&gt;Ueli&lt;/strong&gt;&lt;/a&gt; is a hidden gem. It’s a productivity launcher similar to Alfred on macOS or Raycast. With Ueli, I can open apps, search files, and even run quick calculations without ever touching my mouse. It’s fast, efficient, and eliminates the need to navigate through endless menus.&lt;/p&gt;




&lt;h2&gt;
  
  
  Chrome Extensions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1. Download All Images&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;One of my favorite Chrome extensions is &lt;a href="https://chromewebstore.google.com/detail/download-all-images/ifipmflagepipjokmbdecpmjbibjnakm?hl=en" rel="noopener noreferrer"&gt;&lt;strong&gt;Download All Images&lt;/strong&gt;&lt;/a&gt;. It’s a lifesaver when I need to download multiple images from a page at once. Whether I’m gathering assets for a project or doing research, this tool saves me countless hours.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;2. Fake Filler&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Testing forms is a regular part of my job because I build projects that has them. &lt;a href="https://chromewebstore.google.com/detail/fake-filler/bnjjngeaknajbdcgpfkgnonkmififhfo" rel="noopener noreferrer"&gt;&lt;strong&gt;Fake Filler&lt;/strong&gt;&lt;/a&gt; automatically fills out forms with dummy data, making the testing process much faster and more efficient. It’s especially handy when working on large projects with numerous input fields.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;3. Awesome Screenshot and Screen Recorder&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;For documentation or sharing ideas with clients, &lt;a href="https://www.awesomescreenshot.com/" rel="noopener noreferrer"&gt;&lt;strong&gt;Awesome Screenshot and Screen Recorder&lt;/strong&gt;&lt;/a&gt; is a must-have. This extension allows me to take full-page screenshots or record my screen, making it perfect for capturing website layouts or creating tutorials. I have never really tried the screen recorder feature though because I have not really seen the need for it yet but the screenshot feature is really good.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;4. VisBug&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://chromewebstore.google.com/detail/visbug/cdockenadnadldjbbgcallicgledbeoc" rel="noopener noreferrer"&gt;&lt;strong&gt;VisBug&lt;/strong&gt;&lt;/a&gt; is a design tool that lets you make quick edits to a webpage’s layout and visuals directly in your browser. It’s great for experimenting with design changes on the fly without diving into the code.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;5. Unhook&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Staying focused on YouTube can be challenging with all the recommended videos and comments fighting for your attention. That’s where &lt;a href="https://chromewebstore.google.com/detail/unhook-remove-youtube-rec/khncfooichmfjbepaaaebmommgaepoid" rel="noopener noreferrer"&gt;&lt;strong&gt;Unhook&lt;/strong&gt;&lt;/a&gt; comes in. This extension removes distractions from YouTube, allowing me to focus on learning.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;6. Other Notable Mentions&lt;/strong&gt;
&lt;/h3&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Excalidraw&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://excalidraw.com/" rel="noopener noreferrer"&gt;&lt;strong&gt;Excalidraw&lt;/strong&gt;&lt;/a&gt; is an amazing tool for creating quick and simple diagrams. If you are a developer or content creator, there are times when you need to visually represent your ideas or workflows. Excalidraw’s hand-drawn style makes it easy to create clear, engaging diagrams without the intimidating complexity of professional design tools. &lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Google Keep&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;For lightweight and accessible note-taking, &lt;a href="https://keep.google.com/" rel="noopener noreferrer"&gt;&lt;strong&gt;Google Keep&lt;/strong&gt;&lt;/a&gt; is a fantastic option. It’s simple, syncs across all your devices, and lets you quickly jot down ideas, lists, or reminders. I particularly love using it for capturing thoughts on the go especially when I am not with my PC. &lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Monkeytype&lt;/strong&gt;: The Essence of Touch Typing
&lt;/h3&gt;

&lt;p&gt;While &lt;a href="https://monkeytype.com/" rel="noopener noreferrer"&gt;&lt;strong&gt;Monkeytype&lt;/strong&gt;&lt;/a&gt; is a fun and interactive typing practice tool, it highlights a skill that’s essential for anyone working with computers: &lt;strong&gt;touch typing&lt;/strong&gt;. Being able to type quickly and accurately without looking at the keyboard is a game-changer for productivity. Touch typing reduces the cognitive load associated with finding keys, allowing you to focus entirely on your work.&lt;/p&gt;




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

&lt;p&gt;Thanks for making it to the end of the article! 🎉 I hope you found it helpful.&lt;/p&gt;

&lt;p&gt;What are your favorite productivity tools or Chrome extensions? Share your recommendations in the comments—I’d love to check them out!&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>webdev</category>
      <category>programming</category>
      <category>javascript</category>
    </item>
    <item>
      <title>How I’m Turning My Side Project Into a Source of Income</title>
      <dc:creator>Amrasakpare Lawrence</dc:creator>
      <pubDate>Thu, 09 Jan 2025 23:00:00 +0000</pubDate>
      <link>https://forem.com/devlawrence/how-im-turning-my-side-project-into-a-source-of-income-2dnb</link>
      <guid>https://forem.com/devlawrence/how-im-turning-my-side-project-into-a-source-of-income-2dnb</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Whatsup guys, So as someone who has always been intrigued by the idea of building something meaningful, I decided to take the step and create a side project. This project is a template system designed to solve a problem I’ve encountered repeatedly: the lack of easy customization in traditional website templates. But beyond solving a problem, this project is also a way for me to explore whether I can build something valuable enough to potentially earn from it and also learn other skills that are not necessarily related to coding. So let’s dive right into the article&lt;/p&gt;

&lt;h3&gt;
  
  
  Why I Started This Project
&lt;/h3&gt;

&lt;p&gt;As unexpected as it might sound, this project began because I ran into a bug while working on something else and needed a distraction. I had always envisioned creating my own portfolio template website someday, and this felt like the right moment to start. In the past, I tried my hand at building traditional website templates for platforms like ThemeForest, which is an incredible platform (though, fun fact, all my submissions were rejected 😅).&lt;/p&gt;

&lt;p&gt;One thing that always bothered me about traditional templates was the amount of time buyers spent tweaking someone else’s code to fit their needs. Sure, documentation is provided, but you know what I mean—most templates don’t offer the flexibility users really need.&lt;/p&gt;

&lt;p&gt;That’s when I thought: What if there was a better way? What if I could create templates that were easy to set up and even easier to customize without constantly diving into the code? That’s how this project started taking shape.&lt;/p&gt;

&lt;h3&gt;
  
  
  What I’m Building
&lt;/h3&gt;

&lt;p&gt;The idea is a template system built with Sanity and Astro. Here’s how it works:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Niche-Specific Templates:&lt;/strong&gt; Users can choose from templates designed for specific industries, such as photography, developers, creative professionals and more.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Seamless Setup:&lt;/strong&gt; After downloading the template, users only need to do a few initial installations in the code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Customizations via Sanity:&lt;/strong&gt; Most updates and tweaks can be done through Sanity’s user-friendly interface, rather than editing code every time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is to provide a tool that’s flexible for developers but also approachable for non-developers. It’s a system that I hope can make building and managing websites more intuitive.&lt;/p&gt;

&lt;h3&gt;
  
  
  The First Step: A Free Photography Template
&lt;/h3&gt;

&lt;p&gt;To kick things off, I’ve built the first template in this system, tailored specifically for photographers. It’s a simple yet functional template designed to showcase photography portfolios effectively. And for now, it’s completely free.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Try It Out&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;You can download the template right now from &lt;a href="https://portfoliokit.netlify.app/" rel="noopener noreferrer"&gt;Portfolio Kit&lt;/a&gt;. Currently, there’s just one template available, but it’s free because I’m looking to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Gather Feedback:&lt;/strong&gt; Understand what users like and what needs improvement.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Validate the Idea:&lt;/strong&gt; See if people find this system helpful and valuable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Learn Marketing:&lt;/strong&gt; Experiment with sharing my work and building an audience around it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you’d like to see how it works in action, check out this &lt;a href="https://youtu.be/vGderZ4cnSU" rel="noopener noreferrer"&gt;YouTube video&lt;/a&gt; where I walk through using the template.&lt;/p&gt;

&lt;h3&gt;
  
  
  What’s Next?
&lt;/h3&gt;

&lt;p&gt;This is just the beginning. I’m already thinking about templates for other niches and exploring ways to make the system even better. But for now, my focus is on getting feedback and learning as much as I can.&lt;/p&gt;

&lt;h3&gt;
  
  
  How You Can Help
&lt;/h3&gt;

&lt;p&gt;If this project resonates with you, here’s how you can get involved:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Try the Photography Template:&lt;/strong&gt; It’s free, and your experience will help me improve.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Share Your Feedback:&lt;/strong&gt; Whether it’s about the design, usability, or setup process, I’d love to hear your thoughts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Spread the Word:&lt;/strong&gt; If you know someone who might find this helpful, let them know about it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;This project is deeply personal to me. It’s not just about creating a product but also about testing myself—can I build something that people find valuable? Can I turn this into something sustainable? These are questions I’m still trying to answer.&lt;/p&gt;

&lt;p&gt;For now, I’m taking it one step at a time. If you’ve read this far, thank you for being part of this journey. Your feedback, support, and even just your interest mean a lot. Let’s see where this goes together.&lt;/p&gt;

</description>
      <category>portfolio</category>
      <category>webdev</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>The Basics of Rate Limiting: How It Works and How to Use It</title>
      <dc:creator>Amrasakpare Lawrence</dc:creator>
      <pubDate>Thu, 31 Oct 2024 23:00:00 +0000</pubDate>
      <link>https://forem.com/devlawrence/the-basics-of-rate-limiting-how-it-works-and-how-to-use-it-5ccp</link>
      <guid>https://forem.com/devlawrence/the-basics-of-rate-limiting-how-it-works-and-how-to-use-it-5ccp</guid>
      <description>&lt;p&gt;Rate limiting is a vital concept in web development. It ensures server stability, efficient resource allocation, and protection against malicious attacks. So In this article, we’ll delve into the essence of rate limiting, its importance, various implementation methods, and practical examples to demonstrate its functionality. let’s dive right in 😉&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Rate Limiting?
&lt;/h2&gt;

&lt;p&gt;Rate limiting is a strategy that is used to control the amount of incoming requests or traffic to a web service or to a server. it helps protect your applications from abuse, ensures fair resource distribution, and maintains service stability.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Use Rate Limiting?
&lt;/h2&gt;

&lt;p&gt;Here are some of the reasons why you should use rate limiting 👇🏽&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Preventing Abuse&lt;/strong&gt;: Stops bots or malicious users from overwhelming the server with requests.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resource Management&lt;/strong&gt;: Ensures fair usage of resources across all users.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security&lt;/strong&gt;: Helps prevent brute-force attacks by limiting attempts of some endpoints in your application.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost Control&lt;/strong&gt;: Helps prevent unexpected charges due to excessive API calls.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance&lt;/strong&gt;: Keeps your server responsive and reduces the risk of downtimes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Types of Rate Limiting
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Fixed Window (or Simple) Rate Limiting&lt;/strong&gt;: This method limits requests within a fixed time window. For example, "100 requests per minute.""&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sliding Window Rate Limiting&lt;/strong&gt;: A dynamic time frame that tracks and limits requests over a recent period, such as the last few minutes or seconds.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Token Bucket Algorithm&lt;/strong&gt;: This method uses a "bucket" filled with tokens to manage requests. Each incoming request consumes a token, and the bucket is refilled at set intervals. This approach allows for bursts of traffic while maintaining an overall rate limit.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Leaky Bucket Algorithm&lt;/strong&gt;: Similar to the token bucket, but with a twist. When the bucket is full, excess requests "leak" out or are discarded, maintaining a steady flow.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;💡 &lt;em&gt;I'm not even going to lie because I don't know much about the Token Bucket and Leaky Bucket algorithms, as I haven't needed them for my current projects. However, Fixed Window and Sliding Window are the most common types you'll encounter. For instance, OpenAI's GPT-4 uses Fixed Window rate limiting with tiered limits—their first tier allows 500 requests per minute This approach can lead to burst traffic, as users might hit their limit just before the window resets.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How Rate Limiting Works
&lt;/h2&gt;

&lt;p&gt;The process typically involves:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Tracking&lt;/strong&gt;: Monitoring how many requests a user (mostly the userId) or IP has made within a specific timeframe.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Threshold&lt;/strong&gt;: Defining a limit (e.g., 100 requests per hour).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Response&lt;/strong&gt;: Sending a warning or blocking further requests when the limit is exceeded (usually with a &lt;code&gt;429 Too Many Requests&lt;/code&gt; HTTP status code).&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Implementing Rate Limiting: Practical Examples
&lt;/h2&gt;

&lt;p&gt;Now that you have a basic understanding of rate limiting and how it works, let's get our hands dirty by implementing it in a project we'll be creating.&lt;/p&gt;

&lt;p&gt;We'll create two projects demonstrating rate limiting:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A &lt;strong&gt;GET&lt;/strong&gt; request example&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;POST&lt;/strong&gt; request example&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Tech Stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Frontend: React (using Vite)&lt;/li&gt;
&lt;li&gt;Backend: Express (Node.js framework)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;GET&lt;/strong&gt; request example
&lt;/h3&gt;

&lt;p&gt;Create a folder with any name of your choice and open it on VS code or whatever code editor you use.&lt;/p&gt;

&lt;p&gt;Inside that folder you've created, create two more folders called frontend and backend. &lt;/p&gt;

&lt;p&gt;After that, cd into the backend folders and enter this command &lt;code&gt;npm init -y&lt;/code&gt; to initialize a &lt;code&gt;package.json&lt;/code&gt; file&lt;/p&gt;

&lt;p&gt;After that install the follow npm packages inside the backend folder 👇🏽&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;npm&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;install&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;cors&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;express-rate-limit&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="n"&gt;npm&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;install&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-D&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;nodemon&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What these do:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;express&lt;/code&gt;: Creates your web server and handles API routes&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;cors&lt;/code&gt;: Allows frontend to communicate with backend safely&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;express-rate-limit&lt;/code&gt;: Protects your API from too many requests&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;nodemon&lt;/code&gt;: Auto-restarts server during development (that's why we use &lt;code&gt;D&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After that, create an &lt;code&gt;index.js&lt;/code&gt; (you can this whatever you want) file because we’ll be using it to set up the rate limiter.&lt;/p&gt;

&lt;p&gt;After you’ve done copy and paste this code that I am going to explain in a bit&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;express&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;rateLimit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;express-rate-limit&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;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Set up rate limiter: 100 requests per 15 minutes&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;limiter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;rateLimit&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;windowMs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// 15 minutes&lt;/span&gt;
  &lt;span class="na"&gt;max&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="c1"&gt;// Limit each IP to 5 requests per `window` (here, per 15 minutes)&lt;/span&gt;
  &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Too many requests from this IP, please try again later.&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="c1"&gt;// Apply the rate limiting middleware to all requests&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;limiter&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;app&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/api/data&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;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="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Welcome to the API!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5000&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;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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Server running on http://localhost:5000&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's what each part does:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;First two lines import our needed packages&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;app = express()&lt;/code&gt; creates our server&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;limiter&lt;/code&gt; is configured with:

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;windowMs&lt;/code&gt;: Sets a 15-minute time window (15 × 60 × 1000 milliseconds)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;max&lt;/code&gt;: Allows 5 requests per IP address in that window&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;message&lt;/code&gt;: The error message users see when they exceed the limit&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Then:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;app.use(limiter)&lt;/code&gt; applies our rate limit to all routes&lt;/li&gt;
&lt;li&gt;We create a simple test route at &lt;code&gt;'/api/data'&lt;/code&gt; that sends a welcome message&lt;/li&gt;
&lt;li&gt;Finally, we start the server on port 5000&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When users hit your API more than 100 times in 15 minutes from the same IP, they'll get the error message instead of accessing the API.&lt;/p&gt;

&lt;p&gt;Now that you know how it works, we want to enable auto-restart by adding to &lt;code&gt;package.json&lt;/code&gt; 👇🏽&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;scripts&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dev&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;nodemon index.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s all for the backend.&lt;/p&gt;

&lt;p&gt;It’s time to set up the frontend.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open a new terminal and &lt;code&gt;cd&lt;/code&gt; into the frontend folder and run 👇🏽
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;npm&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;create&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;vite&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="nx"&gt;latest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Go through the following instructions and I’ll advise you select JavaScript if you don’t know typescript&lt;/li&gt;
&lt;li&gt;You can do a little clean up by getting rid of some files you won’t need. here is how mine looks&lt;/li&gt;
&lt;/ul&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%2F1s6hujc489swr7io4tz3.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%2F1s6hujc489swr7io4tz3.png" alt="Folder structure" width="352" height="603"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Once you are done, open the &lt;code&gt;App.jsx&lt;/code&gt; and paste this code that I’ll explain 👇🏽
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;  &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;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="nx"&gt;axios&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;axios&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;App&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setResponse&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="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;setError&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;fetchData&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="nf"&gt;setError&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="c1"&gt;// Reset error state before making a request&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&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;axios&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;http://localhost:5000/api/data&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nf"&gt;setResponse&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="nx"&gt;data&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="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="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;setError&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="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;data&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 occurred while fetching data&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"App"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;header&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"App-header"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Rate Limiting Test with Express&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;fetchData&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Fetch Data from Server&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Server Response: &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="si"&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;red&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Error: &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;header&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Here's what's happening:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We import &lt;code&gt;useState&lt;/code&gt; for managing data and &lt;code&gt;axios&lt;/code&gt; for making API requests&lt;/li&gt;
&lt;li&gt;We create two state variables:

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;response&lt;/code&gt;: Stores successful API responses&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;error&lt;/code&gt;: Stores any error messages&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;fetchData&lt;/code&gt; function:

&lt;ul&gt;
&lt;li&gt;Gets called when button is clicked&lt;/li&gt;
&lt;li&gt;Tries to fetch data from our API&lt;/li&gt;
&lt;li&gt;Updates either &lt;code&gt;response&lt;/code&gt; or &lt;code&gt;error&lt;/code&gt; state&lt;/li&gt;
&lt;li&gt;Uses &lt;code&gt;try/catch&lt;/code&gt; to handle success and errors&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The UI shows:

&lt;ul&gt;
&lt;li&gt;A title&lt;/li&gt;
&lt;li&gt;A button to trigger requests&lt;/li&gt;
&lt;li&gt;The API response (if successful)&lt;/li&gt;
&lt;li&gt;Error messages in red (if request fails)
When you click the button too many times within 15 minutes, you'll see the rate limit error message because of our backend restrictions!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That’s all about the GET request example. Let’s move on to the next example&lt;/p&gt;

&lt;h3&gt;
  
  
  POST request example
&lt;/h3&gt;

&lt;p&gt;For this example, you can decide to comment out the code of the first example and paste this code 👇🏽&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;express&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;express&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;cors&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;cors&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;rateLimit&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;express-rate-limit&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;bodyParser&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;body-parser&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;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;cors&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bodyParser&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;limiter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;rateLimit&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;windowMs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// 15 minutes&lt;/span&gt;
  &lt;span class="na"&gt;max&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="c1"&gt;// limit each IP to 100 requests per windowMs&lt;/span&gt;
  &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Too many requests from this IP, please try again after 15 minutes&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&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/submit-form&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;limiter&lt;/span&gt;&lt;span class="p"&gt;,&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;email&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="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="c1"&gt;// Simulate processing form data&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="s2"&gt;`Received form submission from &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; (&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;): &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;res&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="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Form has been submitted successfully!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5000&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="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="s2"&gt;`Listening on port &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can see that most of the code are the same with the first example but here are just some key difference 👇🏽&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Added &lt;code&gt;bodyParser&lt;/code&gt; to handle form data&lt;/li&gt;
&lt;li&gt;Creates a POST endpoint that processes form submissions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also paste this code on the frontend as well&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;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="nx"&gt;axios&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;axios&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;App&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="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="nx"&gt;setFormData&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="na"&gt;name&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="na"&gt;email&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="na"&gt;message&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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setResponse&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="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;setError&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;handleInputChange&lt;/span&gt; &lt;span class="o"&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="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;value&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&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;setFormData&lt;/span&gt;&lt;span class="p"&gt;({&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="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;value&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;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="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;setError&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="c1"&gt;// Reset error state before making a request&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&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;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&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:5000/api/submit-form&lt;/span&gt;&lt;span class="dl"&gt;"&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="p"&gt;);&lt;/span&gt;
      &lt;span class="nf"&gt;setResponse&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="nx"&gt;data&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="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="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;setError&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="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;data&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 occurred while submitting the form&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="p"&gt;};&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"App"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;header&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"App-header"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Rate Limiting Form Submission with Express&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt; &lt;span class="na"&gt;onSubmit&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleSubmit&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Name:&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt;
              &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt;
              &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;
              &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
              &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleInputChange&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
              &lt;span class="na"&gt;required&lt;/span&gt;
            &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Email:&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt;
              &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;
              &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;
              &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
              &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleInputChange&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
              &lt;span class="na"&gt;required&lt;/span&gt;
            &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Message:&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;textarea&lt;/span&gt;
              &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"message"&lt;/span&gt;
              &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
              &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleInputChange&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
              &lt;span class="na"&gt;required&lt;/span&gt;
            &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Submit&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;color&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&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Server Response: &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="si"&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;red&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Error: &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;header&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Here, we're simply making a request to the server through a form. Let's look at how this differs from the GET example:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Uses a form instead of a single button&lt;/li&gt;
&lt;li&gt;Manages form state with &lt;code&gt;formData&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Handles input changes with &lt;code&gt;handleInputChange&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Uses POST request instead of GET&lt;/li&gt;
&lt;li&gt;Shows success message in green&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The form allows 5 submissions in 15 minutes - after that, users see the rate limit error message.&lt;/p&gt;

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

&lt;p&gt;Alright guys, congrats on getting to the end of this article 🎉. I hope you now have an idea on how rate limiting works and why you should use it on your projects especially if you are working on bigger projects that involves money. If you have any questions, feel free to ask in the comment. Happy coding 🤠&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to Route Multiple Paystack Webhooks with one Webhook URL</title>
      <dc:creator>Amrasakpare Lawrence</dc:creator>
      <pubDate>Thu, 24 Oct 2024 23:00:00 +0000</pubDate>
      <link>https://forem.com/devlawrence/how-to-route-multiple-paystack-webhooks-with-one-webhook-url-1d2m</link>
      <guid>https://forem.com/devlawrence/how-to-route-multiple-paystack-webhooks-with-one-webhook-url-1d2m</guid>
      <description>&lt;p&gt;Paystack offers powerful payment solutions for businesses in Nigeria and across Africa, but one common challenge for developers is the limitation of using only one webhook URL on the Paystack dashboard. For developers managing multiple projects, this restriction can become a major issue, especially when dealing with various applications or environments that require different webhook handling processes.&lt;/p&gt;

&lt;p&gt;Fortunately, Hookdeck offers an easy solution to route webhooks from a single Paystack URL to multiple endpoints across various projects. In this article, we’ll learn how to route multiple webhooks on your paystack projects with one webhook URL using Hookdeck. Let’s dive right in 😉&lt;/p&gt;

&lt;h2&gt;
  
  
  Why You Might Need Multiple Webhook Endpoints for Paystack
&lt;/h2&gt;

&lt;p&gt;So before we go into main stuff, let's examine why having multiple webhook endpoints is necessary 👇🏽&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Managing Multiple Projects:&lt;/strong&gt; If you're handling more than one application that needs to process payment events, routing all webhooks to a single URL won't suffice. Basically what this means is since Paystack only allows one webhook URL, you'd need a way to separate or "route" the incoming webhooks to different places, depending on which project they are meant for and a single URL for all projects won't be able to distinguish between them or allow for tailored responses.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Environment Separation:&lt;/strong&gt; You may want to route webhooks to different environments (e.g., development, staging, production (this is basically ) to ensure events are handled correctly without interfering with your live environment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Custom Processing Logic:&lt;/strong&gt; Different applications or modules might require unique logic to process events, which can be difficult to achieve through a single webhook endpoint.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;With these scenarios in mind, let's see how Hookdeck makes managing multiple Paystack webhooks easier.&lt;/p&gt;

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

&lt;p&gt;Hookdeck is a webhook infrastructure service that allows you to receive, manage, and route webhooks with ease. It acts as an intermediary between your application and webhook providers (like Paystack), enabling you to process webhooks more reliably and flexibly.&lt;/p&gt;

&lt;p&gt;One of Hookdeck's powerful features is the ability to route incoming webhook events to multiple destinations based on the rules you define.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Use Hookdeck with Paystack
&lt;/h2&gt;

&lt;p&gt;Now that you have a basic idea on what hookdeck is, Let’s now walk through the process of setting up Hookdeck to manage and route multiple Paystack webhooks. 👇🏼&lt;/p&gt;

&lt;h3&gt;
  
  
  1. &lt;strong&gt;Create a Hookdeck Account&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The first step is to sign up for a Hookdeck account if you haven't already. You can create a free account on their &lt;a href="https://hookdeck.com/" rel="noopener noreferrer"&gt;website&lt;/a&gt;, which offers all the essential features to get started.&lt;/p&gt;

&lt;p&gt;💡 if for some reason the website does not open on your browser, you can download &lt;a href="https://developers.cloudflare.com/cloudflare-one/connections/connect-devices/warp/download-warp/#_top" rel="noopener noreferrer"&gt;cloudfare warp&lt;/a&gt;. which is a free VPN service that uses Cloudflare's global network to improve your internet connection's speed, security, and privacy. that being said. let’s move on to the next step.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. &lt;strong&gt;Set Up a New Connection on Hookdeck&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;After signing up, you’ll need to create a connection in Hookdeck. A connection basically acts as a single webhook endpoint that you’ll later use on your Paystack dashboard.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In your Hookdeck dashboard, click on &lt;strong&gt;Connection&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&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%2F4ajmvmw1e4gd858uh6bc.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%2F4ajmvmw1e4gd858uh6bc.png" alt="Create connection" width="800" height="371"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;After clicking on create connection you will directed to another page where you have to do a couple of things 👇🏽&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;You have to define your request source by adding a source name (e.g., Paystack webhook or anything you want).&lt;/li&gt;
&lt;/ul&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%2Fy2y0ksrf84deipa5c2vg.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%2Fy2y0ksrf84deipa5c2vg.png" alt="source name" width="800" height="311"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You also need to define your event destination by adding a destination name and an endpoint URL. So if you already have an endpoint you are using as your webhook endpoint, on paystack you can add that one. lastly, you can leave the destination type as it is.&lt;/li&gt;
&lt;/ul&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%2F9ts7uxy9lf529bju7b8q.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%2F9ts7uxy9lf529bju7b8q.png" alt="Destination name" width="800" height="418"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Define your connection rules: I haven't needed this for my current projects. However, it allows you to set up different rules to listen for various events. This is particularly useful if you're using one source URL for multiple platforms (like Paystack, Stripe, or Shopify). You'd set up rules to differentiate between them. It's also helpful if you have two Paystack projects—one using a subscription method and the other using the normal charge method (which we'll discuss in step 4). But if you're just using one webhook URL for all your Paystack projects, you can skip this step.&lt;/li&gt;
&lt;/ul&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%2Ftedu83uln3ccrivf9joa.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%2Ftedu83uln3ccrivf9joa.png" alt="Connection rules" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lastly, set up a connection name. While optional, it's recommended if you have multiple connections with the same source and destination, or if you use the API. Once you're done, click on &lt;strong&gt;Create&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&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%2Fw1xj7awl4nu7rpvibm8r.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%2Fw1xj7awl4nu7rpvibm8r.png" alt="Name your connection" width="800" height="259"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You should see something like this after creating a connection. 👇🏽&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%2Fr5xzmu47zbsgvfwzrrbp.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%2Fr5xzmu47zbsgvfwzrrbp.png" alt="Connection created" width="800" height="554"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. &lt;strong&gt;Configure the Paystack Webhook&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Now that you have a Hookdeck URL, copy it and go to your Paystack dashboard to configure your webhook:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Log in to your Paystack dashboard.&lt;/li&gt;
&lt;li&gt;Navigate to &lt;strong&gt;Settings&lt;/strong&gt; &amp;gt; &lt;strong&gt;Webhooks&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Replace your current webhook URL with the one provided by Hookdeck.&lt;/li&gt;
&lt;li&gt;Save the changes.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;At this point, all Paystack events will be sent to the Hookdeck URL, which will act as your single point of entry for webhook requests.&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%2Fvehlopw8vm39r51qgghz.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%2Fvehlopw8vm39r51qgghz.png" alt="Connection chain" width="800" height="62"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4. &lt;strong&gt;Set Up Destinations in Hookdeck&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Once your Hookdeck connection is receiving Paystack events, the next step is to configure &lt;strong&gt;Destinations&lt;/strong&gt;, which is how Hookdeck forwards your webhooks to the appropriate endpoints based on the events.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to your Hookdeck dashboard and click on the &lt;strong&gt;Connection&lt;/strong&gt; you created for Paystack.&lt;/li&gt;
&lt;li&gt;Click on the connection chain - in this case it will be the &lt;code&gt;test-connection&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Once you've clicked on the &lt;code&gt;test-connection&lt;/code&gt;, you can use Hookdeck’s built-in filters to control which events are forwarded to which destination. For example:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;To forward only successful payment events to a specific endpoint, you can filter the events by &lt;code&gt;event.type == "charge.success"&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;For subscription-related events, you can filter with &lt;code&gt;event.type == "subscription.create"&lt;/code&gt; and route them to your other project.&lt;/li&gt;
&lt;/ul&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%2Fly02o6wykbdgtixbt6oe.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%2Fly02o6wykbdgtixbt6oe.png" alt="Filter connection" width="582" height="760"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Save these settings. Now, Hookdeck will automatically forward specific Paystack events to the right endpoints based on the filters you’ve applied.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  5. &lt;strong&gt;Testing and Monitoring&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Once your routes are set up, it's crucial to test and monitor the webhook events to ensure they’re being routed correctly. Hookdeck offers useful tools to help with this.&lt;/p&gt;

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

&lt;p&gt;That’s all guys, and congrats for getting to the end of the article 🎉. Let me know if you had issues with any part of the code on the comment section. Till next time and Happy coding 😀&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Should you really Roll your own auth?</title>
      <dc:creator>Amrasakpare Lawrence</dc:creator>
      <pubDate>Thu, 20 Jun 2024 23:00:00 +0000</pubDate>
      <link>https://forem.com/devlawrence/should-you-really-roll-your-own-auth-4dj</link>
      <guid>https://forem.com/devlawrence/should-you-really-roll-your-own-auth-4dj</guid>
      <description>&lt;p&gt;Hey guys, In this article, I want to discuss whether it's better to build your own authentication system or to use a third-party service provider. Let’s dive right in 😃&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Consider Building Your Own Authentication?
&lt;/h2&gt;

&lt;p&gt;First, let's consider the &lt;strong&gt;"WHY"&lt;/strong&gt; behind building your own authentication system from scratch. The decision depends significantly on your role and the kind of application you are developing. For instance, if you are a backend developer working for a company, they likely already have their own authentication system in place. However, the situation might be different if you're a freelancer (hello🙂), or frontend developer working for clients or personal projects.&lt;/p&gt;

&lt;p&gt;Some people advocate for building your own authentication, while others recommend using third-party services like Clerk, Auth0, Kinde, and others. I'll outline the pros and cons of each approach and share my perspective on both solutions.&lt;/p&gt;

&lt;h2&gt;
  
  
  👨🏽‍💻 The Freelancer's Perspective
&lt;/h2&gt;

&lt;p&gt;As a freelancer, if I have projects to deliver to clients, creating authentication from scratch is not the best solution. Here’s why:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Time Constraints&lt;/strong&gt;: Freelancers often work with tight deadlines. Building a robust authentication system from scratch is time-consuming and complex, which can delay project delivery.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resource Management&lt;/strong&gt;: Freelancers usually handle multiple aspects of a project. Using a third-party service for authentication allows them to focus on other important tasks, enhancing overall productivity.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost&lt;/strong&gt;: While third-party services can be expensive, many offer generous free tiers that are sufficient for small to medium projects. This can be a cost-effective solution for freelancers working on budget-constrained projects.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Dependency&lt;/strong&gt;: Relying on an external provider might raise concerns about reliability and data security.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost at Scale&lt;/strong&gt;: While initial costs might be low, they can increase significantly as the project scales.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;💡 But at the end of day the client does not really care what you use. They just want to see results.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  👨🏽‍💻 The Frontend Developer's Perspective
&lt;/h2&gt;

&lt;p&gt;As a frontend developer, or more broadly, as a software engineer focused on building frontend applications, the scenario is slightly different:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ease of Integration&lt;/strong&gt;: Frontend developers can easily integrate third-party authentication services without delving into the complexities of backend systems.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Time Efficiency&lt;/strong&gt;: Using third-party services allows frontend developers to concentrate on the UI/UX aspects of the project, ensuring a better user experience.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Learning Opportunity&lt;/strong&gt;: While it’s beneficial to understand how authentication works, building it from scratch isn’t always necessary for frontend-focused projects. However, gaining some knowledge can help when integrating third-party services securely.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Limited Control&lt;/strong&gt;: Depending on third-party services means you have less control over the authentication process and data management.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Potential Integration Issues&lt;/strong&gt;: There can be occasional compatibility issues with other parts of the application.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  👨🏽‍💻 The Backend Developer's Perspective
&lt;/h2&gt;

&lt;p&gt;For backend developers, the line becomes blurry, and here's why:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Control and Customization&lt;/strong&gt;: Building your own authentication system offers greater control over the implementation, allowing customization to meet specific security and business requirements.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security Considerations&lt;/strong&gt;: Backend developers often need to ensure high security standards. While third-party services are secure, having control over the authentication process allows for more tailored security measures.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability and Maintenance&lt;/strong&gt;: Maintaining your own system can be challenging but rewarding. Backend developers need to weigh the benefits of customization against the overhead of maintaining and scaling the system.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Time and Resources&lt;/strong&gt;: Developing and maintaining a custom authentication system requires significant time and resources.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Complexity&lt;/strong&gt;: Ensuring that the system is secure and scalable adds to the complexity of the project.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;💡 Here is thing, you are a backend dev which means you chose the path of long suffering, So you don’t need to take the cons into consideration&lt;/em&gt; 🙂.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Questions
&lt;/h2&gt;

&lt;p&gt;Here are some common questions I was hoping you’d ask as well the answers in mind 👇🏽&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;What if my project scales quickly?&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using a third-party service can be beneficial as they often provide scalable solutions that can handle increased loads without significant changes.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Are third-party services secure enough?&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most third-party services invest heavily in security and compliance, often exceeding what a small team can implement. However, always review their security policies and practices to ensure they meet your requirements.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;💡 But you should try out&lt;/em&gt; &lt;a href="https://clerk.dev/"&gt;clerk.dev&lt;/a&gt; &lt;em&gt;though 🙂&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Can I switch from a third-party service to my own system later?&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Yes, but it can be complex. Plan for such transitions by abstracting the authentication layer in your application to make future changes easier.&lt;/p&gt;

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

&lt;p&gt;Alright guys, Thanks for getting to this part of the article 🎊 🎊. The decision to build your own authentication system or use a third-party service depends on your role, project requirements, and constraints. Freelancers and frontend developers might find third-party services more practical due to time constraints and workload, while backend developers might benefit from the flexibility and control of building their own systems. Regardless of your choice, it's crucial to weigh the pros and cons and make an informed decision that best suits your needs.&lt;/p&gt;

&lt;p&gt;Have an amazing weekend and see you next week 🙂&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>authjs</category>
      <category>javascript</category>
      <category>programming</category>
    </item>
    <item>
      <title>Cyclic has shut down and I am migrating my data to another service</title>
      <dc:creator>Amrasakpare Lawrence</dc:creator>
      <pubDate>Thu, 13 Jun 2024 23:00:00 +0000</pubDate>
      <link>https://forem.com/devlawrence/cyclic-has-shut-down-and-i-am-migrating-my-data-to-another-service-4nj6</link>
      <guid>https://forem.com/devlawrence/cyclic-has-shut-down-and-i-am-migrating-my-data-to-another-service-4nj6</guid>
      <description>&lt;p&gt;A few weeks ago, I wrote an article on deploying your full-stack application, which you can find &lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/devlawrence/how-to-deploy-your-fullstack-website-my-approach-3f6l"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;One of the hosting services I discussed was Cyclic. Unfortunately, Cyclic has since shut down. In this article, I'll explore why I believe they closed and share the best alternative I've found for migrating my data to a new platform. Let's dive in! 😉&lt;/p&gt;

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

&lt;p&gt;Cyclic is a popular platform that provided hosting solutions for full-stack web applications specifically for JavaScript application as at the time I deployed my application to their services.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why did they shut down?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.cyclic.sh/posts/cyclic-is-shutting-down/"&gt;Here&lt;/a&gt; is an article I found on their website as to why they are shutting down but I honestly,  I think the exact reasons were not disclosed, but here are some potential factors that could have led to Cyclic's decision to cease operations 👇🏽&lt;/p&gt;

&lt;h3&gt;
  
  
  💸 Financial challenges
&lt;/h3&gt;

&lt;p&gt;Running a hosting platform requires significant infrastructure investments and operational costs. &lt;/p&gt;

&lt;p&gt;And I believe that they were not able to get more customers to offset their expenses and this was what they said on their blog 👉🏽 &lt;strong&gt;“we were not able to sell enough to make it self sustaining”.&lt;/strong&gt; And why I am saying this from a good place. I felt they gave just too much for free without striking a proper balance in their pricing tier.&lt;/p&gt;

&lt;h3&gt;
  
  
  💻 Technical or operational challenges
&lt;/h3&gt;

&lt;p&gt;Maintaining a hosting platform can be technically complex, and issues related to scalability, security, or other operational challenges could have made it increasingly difficult for Cyclic to continue providing reliable services.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔀 Strategic shift
&lt;/h3&gt;

&lt;p&gt;Companies sometimes pivot their focus or change their business strategy, which could involve discontinuing existing products or services.&lt;/p&gt;

&lt;p&gt;While there may be other reasons I haven't mentioned, I believe these three factors contributed to their shutdown.&lt;/p&gt;

&lt;p&gt;So this now leads us to 👇🏽&lt;/p&gt;

&lt;h2&gt;
  
  
  Where am I migrating my data to?
&lt;/h2&gt;

&lt;p&gt;So if you went through the first link of the article you might known already. But nevertheless, I will be migrating my data to the Sanity(sanity.io). So Sanity is a headless CMS (Content management System) which means the content like text, images, videos, etc. is stored separately from the way it's presented on the website. And the cool feature I like about them is that they offer a cloud-hosted option where you don't need to manage your own server infrastructure.&lt;/p&gt;

&lt;p&gt;So my full stack website &lt;a href="https://nike-webstores.netlify.app/"&gt;Nike webstore&lt;/a&gt; (under maintenance though 😅) was initially built with the MERN stack so you can imagine moving my data from mongoDB to Sanity and I also have to use another method in querying my data.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I learned from all these?
&lt;/h2&gt;

&lt;p&gt;Besides learning new techniques for migrating data without breaking anything (yet 😅), I also gathered some valuable insights: always strike the right balance between free and paid offerings to incentivize upgrades. Continuously evaluate and adjust pricing models as your product and the market evolve. Focus on converting free users to paying customers through effective strategies. Diversify revenue streams beyond just a freemium model. Consistently improve the product and user experience to justify paid plans.  (💡 Just a side note: avoid doing this from your main branch. 😅) 👇🏽&lt;/p&gt;

&lt;p&gt;💡 &lt;em&gt;Just to be clear, I really enjoyed Cyclic services because they really made deploying full stack applications very easy which was why I even wrote the article.&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;Alright guys, that’s the end of the article 🎊🎊. I hope you found it informative, and I would love to hear about better alternatives for migrating your MERN stack app to free web services. Have an amazing weekend, and see you next week! 😃.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>programming</category>
      <category>learning</category>
    </item>
    <item>
      <title>Getting Started with SSR</title>
      <dc:creator>Amrasakpare Lawrence</dc:creator>
      <pubDate>Thu, 06 Jun 2024 23:00:00 +0000</pubDate>
      <link>https://forem.com/devlawrence/getting-started-with-ssr-123j</link>
      <guid>https://forem.com/devlawrence/getting-started-with-ssr-123j</guid>
      <description>&lt;p&gt;Hey guys, recently, I've been exploring Next.js which is framework that is built on top of react to streamline web application development, and I've come across a technique it uses for rendering web pages. It's quite distinct from the familiar client-side rendering (CSR) approach that many of us are accustomed to. This technique is known as Server-Side Rendering (SSR). &lt;/p&gt;

&lt;p&gt;In this article, we'll delve into what SSR entails, how it differs from CSR, and uncover other intriguing aspects. Let’s dive right 😉&lt;/p&gt;

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

&lt;p&gt;Server-side rendering (SSR) is a technique in web development where the web page is generated on the server before being sent to the user's browser. This means that the initial content of the page is already rendered and ready to be displayed when the user requests it.&lt;/p&gt;

&lt;p&gt;Here's a breakdown of SSR in the context of &lt;strong&gt;Next.js:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When a user visits a Next.js page by making an http request, the server executes the necessary code to generate the complete HTML content for that page because it does page splitting by default. This includes the initial data and markup.&lt;/li&gt;
&lt;li&gt;The generated HTML is then sent to the user's browser.&lt;/li&gt;
&lt;li&gt;Once the browser receives the HTML, it can immediately render the content without having to wait for any additional JavaScript to be downloaded and executed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This approach offers several advantages such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Improved SEO:&lt;/strong&gt; Search engines can easily crawl and index the content of SSR-rendered pages, which can boost your website's search ranking.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Faster initial load times:&lt;/strong&gt; Since the initial HTML is already generated, users see the content of the page almost instantly, leading to a better perceived performance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enhanced user experience:&lt;/strong&gt; Users don't have to wait for JavaScript to load before they can interact with the page.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So what sets it apart from client-side rendering? They both seem to render right away, right?&lt;/p&gt;

&lt;h2&gt;
  
  
  Difference between CSR and SSR
&lt;/h2&gt;

&lt;p&gt;You're correct that both Server-Side Rendering (SSR) and client-side rendering (CSR), the default method in React, can provide an immediate rendering experience for users. However, there's a key difference in when the rendering happens 👇🏽&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In SSR (with Next.js), the server renders the initial HTML on the server, including the data needed for the page. This HTML is then sent to the browser, resulting in a faster initial load time because the content is already there.&lt;/li&gt;
&lt;li&gt;In CSR (normal React), the browser receives an empty HTML shell and then fetches the necessary JavaScript code to render the page content. This can lead to a slight delay(  before the user sees the content, especially on slower connections.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here is an analogy to differentiate the two&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Imagine SSR as getting a pre-made meal at a restaurant. You receive your food instantly, and then the chef prepares any additional dishes you ordered.&lt;/li&gt;
&lt;li&gt;On the other hand, CSR is like ordering a custom meal. The chef needs to cook everything from scratch, so it takes a bit longer to get your food.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Considerations for SSR with Next.js
&lt;/h2&gt;

&lt;p&gt;Here are two additional things to keep in mind about SSR with Next.js&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Data fetching:&lt;/strong&gt;  SSR is great for SEO and initial load times, but it can add some overhead to your server since it needs to generate the HTML for each request. To optimize this, Next.js offers techniques like &lt;code&gt;getStaticProps&lt;/code&gt; and &lt;code&gt;getServerSideProps&lt;/code&gt; for fetching data efficiently on the server-side.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not ideal for highly dynamic content:&lt;/strong&gt;  SSR is less suitable for web applications with constant updates or user interactions that heavily rely on JavaScript. In these cases, client-side rendering or a hybrid approach might be more appropriate.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Understanding &lt;code&gt;getStaticProps&lt;/code&gt; and &lt;code&gt;getServerSideProps&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;In Next.js, &lt;code&gt;getStaticProps&lt;/code&gt; and &lt;code&gt;getServerSideProps&lt;/code&gt; are functions specifically designed for data fetching on the server-side, addressing the potential drawbacks of SSR that we talked about earlier. Here's a breakdown of what they are and the difference between them 👇🏽&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;getStaticProps&lt;/code&gt;:&lt;/strong&gt; This is a function that is ideal for pre-rendering data at build time. It's perfect for content that doesn't update frequently, like blog posts or product pages. The fetched data is directly included in the static HTML, resulting in super-fast load times and excellent SEO since search engines can easily index the content. Here is an example 👇🏽&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;HomePage&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Home Page&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Data fetched at build time: &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;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="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Simulate fetching data at build time&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;This data was fetched at build time.&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="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;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;HomePage&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;Here is what is going on from the code above 👇🏽&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We have a simple home page component (&lt;strong&gt;&lt;code&gt;HomePage&lt;/code&gt;&lt;/strong&gt;) that receives some data as a prop.&lt;/li&gt;
&lt;li&gt;We use &lt;strong&gt;&lt;code&gt;getStaticProps&lt;/code&gt;&lt;/strong&gt; to fetch data at build time. Here, we're simulating fetching data synchronously.&lt;/li&gt;
&lt;li&gt;The fetched data is passed to the &lt;strong&gt;&lt;code&gt;HomePage&lt;/code&gt;&lt;/strong&gt; component as props.&lt;/li&gt;
&lt;/ul&gt;


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

&lt;p&gt;&lt;strong&gt;&lt;code&gt;getServerSideProps&lt;/code&gt;:&lt;/strong&gt; This is a function that fetches data on the server-side just before a page is rendered for each request. It's a good choice for content that needs to be dynamic or personalized based on the user, like shopping carts or user profiles. While it might add a slight delay compared to &lt;code&gt;getStaticProps&lt;/code&gt;, it ensures the data is always up-to-date. Here is an example 👇🏽&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight jsx"&gt;&lt;code&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;AboutPage&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;About Page&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Data fetched on each request: &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;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="c1"&gt;// Simulate fetching data on each request&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;This data is fetched on each request.&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="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;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;AboutPage&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

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



&lt;p&gt;Here is what is going on from the code above 👇🏽&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We also have a simple about page component (&lt;strong&gt;&lt;code&gt;AboutPage&lt;/code&gt;&lt;/strong&gt;) that receives some data as a prop.&lt;/li&gt;
&lt;li&gt;We use &lt;strong&gt;&lt;code&gt;getServerSideProps&lt;/code&gt;&lt;/strong&gt; to fetch data on each request. Here, we're simulating fetching data synchronously.&lt;/li&gt;
&lt;li&gt;The fetched data is passed to the &lt;strong&gt;&lt;code&gt;AboutPage&lt;/code&gt;&lt;/strong&gt; component as props.&lt;/li&gt;
&lt;/ul&gt;


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

&lt;p&gt;💡 &lt;em&gt;I hope you get a basic idea on how &lt;code&gt;getStaticProps&lt;/code&gt; and&lt;/em&gt; &lt;strong&gt;&lt;code&gt;getServerSideProps&lt;/code&gt;&lt;/strong&gt;  &lt;em&gt;works now&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;These examples are quite basic and demonstrate the fundamental usage of &lt;strong&gt;&lt;code&gt;getStaticProps&lt;/code&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;code&gt;getServerSideProps&lt;/code&gt;&lt;/strong&gt;. But in real-world scenarios, you would typically use these functions to fetch data from external sources like APIs or databases.&lt;/p&gt;

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

&lt;p&gt;Thank you for reaching the end of the article! 🎉 I hope you found it informative and insightful. If you have any questions or contributions, feel free to leave them in the comments section below. Wishing you an amazing weekend! 😀&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>nextjs</category>
      <category>beginners</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Camp Activity Form Markup With Glam - V2</title>
      <dc:creator>Amrasakpare Lawrence</dc:creator>
      <pubDate>Fri, 29 Mar 2024 04:06:05 +0000</pubDate>
      <link>https://forem.com/devlawrence/camp-activity-form-markup-with-glam-v2-1ik8</link>
      <guid>https://forem.com/devlawrence/camp-activity-form-markup-with-glam-v2-1ik8</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for DEV Challenge v24.03.20, Glam Up My Markup: Camp Activities&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;I built a camp activity inquiries form to get feedback from campers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://camping-form.netlify.app/"&gt;Live Demo&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/dev-lawrence/dev-challenge-v2"&gt;Source code&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Journey
&lt;/h2&gt;

&lt;p&gt;I've already submitted version 1, but I wasn't satisfied with its creativity and overall appearance. So, I embarked on creating a new version. This time, I focused on utilizing the users' selected activity options to dynamically change the background image of the page, which I'm quite pleased with. As I'm writing this, I've even come up with another idea to enhance it further 😅, but for now, I'll stick with what I have. I genuinely hope there are similar challenges in the future because I found it both enjoyable and challenging to handle most aspects through JavaScript rather than the conventional methods.&lt;/p&gt;

</description>
      <category>frontendchallenge</category>
      <category>devchallenge</category>
      <category>css</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Serverless Function - Should You Use Them?</title>
      <dc:creator>Amrasakpare Lawrence</dc:creator>
      <pubDate>Thu, 28 Mar 2024 23:00:00 +0000</pubDate>
      <link>https://forem.com/devlawrence/serverless-function-should-you-use-them-460c</link>
      <guid>https://forem.com/devlawrence/serverless-function-should-you-use-them-460c</guid>
      <description>&lt;p&gt;In this ever-changing world of cloud computing, &lt;strong&gt;"serverless functions"&lt;/strong&gt; has become a widely discussed term. This new way of developing and deploying applications has revolutionized the process, offering developers a more efficient and streamlined approach. In this article you are going to learn what serverless functions are, how they operate, its benefits and drawbacks, popular use cases, types of serverless functions, and the leading cloud platform providers in this space. Let’s dive right in 😉&lt;/p&gt;

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

&lt;p&gt;Serverless functions at it’s core are basically functions that run on the cloud. It's a cloud-based development model where you, the developer, focus on writing code (functions) without worrying about server management. The cloud provider handles everything behind the scenes: provisioning servers, scaling resources, and maintaining infrastructure. You simply deploy your code, and the provider takes care of the rest.&lt;/p&gt;

&lt;p&gt;There's a quote that often comes to mind from my computer engineering teacher: "Every wireless connection must have a wired backbone." This is particularly relevant in the context of serverless functions because although they operate without explicit server management, there's still a server infrastructure working behind the scenes.&lt;/p&gt;

&lt;h2&gt;
  
  
  How do Serverless Functions work?
&lt;/h2&gt;

&lt;p&gt;Serverless functions are triggered by events. These events can be anything from an HTTP request to a change in a database. When an event occurs, the cloud provider wakes up your function, executes your code, and then puts your function back to sleep once finished. This event-driven approach ensures that resources are only used when needed, making it highly cost-effective.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Why Go Serverless?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Here are some reasons you should consider using serverless 👇🏽&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Faster Development:&lt;/strong&gt; No server management translates to quicker development cycles. You can focus on writing code and deploying functions without getting bogged down in infrastructure concerns.
&lt;em&gt;💡 You do have to set up your environment variables yourself though.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability:&lt;/strong&gt; Serverless applications scale automatically based on demand. You don't need to worry about provisioning extra servers during peak traffic or dealing with underutilized resources during downtime.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost-Effectiveness:&lt;/strong&gt; You only pay for the resources you use. Since serverless functions are event-driven, you're not charged for idle time which is really nice.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Types of Serverless Functions&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;There are two main types of serverless functions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;HTTP-triggered functions:&lt;/strong&gt; Invoked by HTTP requests, making them ideal for building APIs and web backends.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Event-triggered functions:&lt;/strong&gt; Respond to various events like changes in databases, file uploads, or messages in queues.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Pros and Cons of Serverless&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Like any technology, serverless has its advantages and disadvantages 👇🏽&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Faster development and deployment&lt;/li&gt;
&lt;li&gt;Automatic scaling&lt;/li&gt;
&lt;li&gt;Cost-effective&lt;/li&gt;
&lt;li&gt;Reduced operational overhead&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Vendor lock-in (code might be specific to a cloud provider's platform)&lt;/li&gt;
&lt;li&gt;Limited control over underlying infrastructure&lt;/li&gt;
&lt;li&gt;Cold start times (functions may experience delays in execution, especially the first time after deployment) - This is a common frustration associated with serverless computing.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Cloud Providers for Serverless&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Most major cloud providers offer serverless platforms, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AWS Lambda by Amazon Web Service&lt;/li&gt;
&lt;li&gt;Azure Functions by Microsoft Azure&lt;/li&gt;
&lt;li&gt;Google Cloud Functions by Google cloud&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AWS Lambda is often considered the most mature and feature-rich serverless computing platform. It has excellent integration with other AWS services, a wide range of runtimes and programming language support, and robust tooling and monitoring capabilities. If your application is heavily invested in the AWS ecosystem or requires advanced features and integrations, AWS Lambda is a solid choice.&lt;/p&gt;

&lt;p&gt;💡 &lt;em&gt;Netlify and Vercel are built on top of AWS Lambda and they both use it for their serverless functions offering.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Personal Opinion&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;I recommend experimenting with a traditional server setup before delving into serverless computing. This way, you can better understand the distinctions between the two approaches.&lt;/p&gt;

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

&lt;p&gt;Thank you for reaching the conclusion of the article! 🎉 🎉 I hope you gained valuable insights. Feel free to share in the comments whether you're currently utilizing serverless functions for your applications and any hurdles you encounter. Looking forward to connecting with you again next week. Have a fantastic weekend! 😉&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Camp Activity Form Markup With Glam</title>
      <dc:creator>Amrasakpare Lawrence</dc:creator>
      <pubDate>Thu, 28 Mar 2024 20:29:38 +0000</pubDate>
      <link>https://forem.com/devlawrence/camp-activity-form-markup-with-glam-i2j</link>
      <guid>https://forem.com/devlawrence/camp-activity-form-markup-with-glam-i2j</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for DEV Challenge v24.03.20, Glam Up My Markup: Camp Activities&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;I built a camp activity inquiries form to get feedback from campers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://camp-activities.netlify.app/"&gt;Live Demo&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/dev-lawrence/dev-challenge"&gt;Source code&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Journey
&lt;/h2&gt;

&lt;p&gt;The experience was both enjoyable and slightly stressful as I had to return to using vanilla JavaScript, which I haven't utilized for some time. Nevertheless, it proved to be a valuable learning journey. I'm proud of how the website turned out, especially considering the minimal planning I invested in it and the need to reacquaint myself with certain JavaScript concepts. I will try to create a better version if there is time.&lt;/p&gt;

</description>
      <category>frontendchallenge</category>
      <category>devchallenge</category>
      <category>css</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
