<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Femi Akinyemi</title>
    <description>The latest articles on DEV Community by Femi Akinyemi (@femi_akinyemi).</description>
    <link>https://dev.to/femi_akinyemi</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F363773%2Ff660be1b-b50b-44cb-b4ff-cdeba2da79ca.jpg</url>
      <title>DEV Community: Femi Akinyemi</title>
      <link>https://dev.to/femi_akinyemi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/femi_akinyemi"/>
    <language>en</language>
    <item>
      <title>What usually slows a WordPress site</title>
      <dc:creator>Femi Akinyemi</dc:creator>
      <pubDate>Sun, 20 Sep 2026 11:29:18 +0000</pubDate>
      <link>https://dev.to/femi_akinyemi/what-usually-slows-a-wordpress-site-d02</link>
      <guid>https://dev.to/femi_akinyemi/what-usually-slows-a-wordpress-site-d02</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Originally published at &lt;a href="https://pafcore.site/what-usually-slows-a-wordpress-site" rel="noopener noreferrer"&gt;pafcore.site/what-usually-slows-a-wordpress-site&lt;/a&gt;. Prefer the canonical link for sharing and SEO.&lt;/p&gt;
&lt;/blockquote&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmqm31qsobx86oo7eiktw.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmqm31qsobx86oo7eiktw.png" alt="WordPress site speed: from a long tip list to a named file" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Blank screen. Late picture. Taps that feel ignored. Then a long tip list that still does not name the file. Here is the plain version, and a free way to find what to fix first.&lt;/p&gt;

&lt;p&gt;WordPress runs a large share of the public web. That success also means a lot of sites feel slow for the same reasons. Owners open Google PageSpeed Insights. They get a score and a scroll of advice. They still leave unsure what to change today.&lt;/p&gt;

&lt;p&gt;This piece is not a plugin hall of fame. It is what people usually feel, what a tip list misses, and how a free &lt;a href="https://pafcore.site" rel="noopener noreferrer"&gt;PafCore&lt;/a&gt; report helps you name the slow file when it can.&lt;/p&gt;

&lt;h2&gt;
  
  
  What people feel first
&lt;/h2&gt;

&lt;p&gt;Before anyone talks about scores, visitors notice the site.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The screen stays blank longer than they expect.&lt;/li&gt;
&lt;li&gt;The big picture shows up late.&lt;/li&gt;
&lt;li&gt;Buttons and menus ignore the first tap.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those moments matter more than a grade on a lab report. A score is useful. It is also incomplete on its own. I wrote about that gap in &lt;a href="https://pafcore.site/why-a-performance-score-is-not-enough" rel="noopener noreferrer"&gt;Why a performance score is not enough&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What usually slows WordPress
&lt;/h2&gt;

&lt;p&gt;Every site is different. Still, the same patterns show up again and again.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Large pictures.&lt;/strong&gt; Hero images, galleries, and blog photos that were never resized for the web. The browser waits. The visitor waits.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Heavy theme and plugin scripts.&lt;/strong&gt; Themes and plugins often load JavaScript and styles on every page, even when that page does not need them. One quiet plugin can cost more than the rest of the theme.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fonts.&lt;/strong&gt; Several font files, or fonts that block text until they finish loading. The page looks empty even when the words are already there.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ads and embeds.&lt;/strong&gt; YouTube, maps, chat widgets, and ad scripts pull work from other servers. Your page waits on them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Weak hosting.&lt;/strong&gt; Cheap shared hosting can make every request slower. It is real. It is not always the first place to look. Measure the page before you buy a bigger plan.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Keep it honest: none of these is always the villain. A lean plugin can be fine. A big image can be fine if it is the right size. Guessing wastes a week. Measuring names the file.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Why a tip list is hard to use
&lt;/h2&gt;

&lt;p&gt;PageSpeed Insights and Lighthouse are free and useful. The tip list is long on purpose. Many tips do not move the score much. Some are already fine for your page.&lt;/p&gt;

&lt;p&gt;People change three things. They run the check again. The number moves. They still cannot tell if the fix worked, or if the page just wobbles from one run to the next. That quiet swing is common. See &lt;a href="https://pafcore.site/why-your-lighthouse-score-changes" rel="noopener noreferrer"&gt;Why your Lighthouse score changes when you did nothing&lt;/a&gt; and &lt;a href="https://pafcore.site/why-faster-barely-moves-your-lighthouse-score" rel="noopener noreferrer"&gt;Why getting faster barely moves your Lighthouse score&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frp1tcrypfwsdcz7c1dks.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frp1tcrypfwsdcz7c1dks.png" alt="Side by side: a long tip list versus a named file and what to fix first" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Left: a scroll of tips. Right: a named file and a clear next step.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What a useful report does
&lt;/h2&gt;

&lt;p&gt;A useful speed report for WordPress should do four simple jobs.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Run the page more than once so you see a middle score, not one lucky screenshot.&lt;/li&gt;
&lt;li&gt;Show how far the score moves on its own (the quiet gap).&lt;/li&gt;
&lt;li&gt;Say what to fix first by points, not by how scary the tip sounds.&lt;/li&gt;
&lt;li&gt;Name the slow file when the measurement can find it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That is what &lt;a href="https://pafcore.site" rel="noopener noreferrer"&gt;PafCore&lt;/a&gt; is built for. Paste a public WordPress URL. You get a free report. No signup. When we can see the cost, we name the file. When we cannot, we still tell you what to try first.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to try it on your WordPress site
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Pick a real page. The home page, or a busy post or product page.&lt;/li&gt;
&lt;li&gt;Paste the full address at &lt;a href="https://pafcore.site" rel="noopener noreferrer"&gt;pafcore.site&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Read the middle score and the quiet gap first.&lt;/li&gt;
&lt;li&gt;Open the top finding. If a file is named, start there.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Use the live public URL. A staging site behind a login will not load the same way for a free public check. Start with what visitors already see.&lt;/p&gt;

&lt;h2&gt;
  
  
  For freelancers and agencies
&lt;/h2&gt;

&lt;p&gt;You already sell WordPress speed work. Clients ask “did we get faster?” A long tip screenshot is hard to explain. A report that names a file is easier to send.&lt;/p&gt;

&lt;p&gt;PafCore can carry your name on the report when white label is on. Share the link. Talk in plain words: what the visitor felt, which file hurt, what you will fix next. Keep one quiet recheck after the fix so you do not celebrate noise.&lt;/p&gt;

&lt;p&gt;If you manage many sites and need schedules, that is &lt;a href="https://pafcore.site/pro" rel="noopener noreferrer"&gt;Pro Watch&lt;/a&gt;. The free report stays free for a one off paste.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Is PageSpeed Insights enough for a WordPress site?
&lt;/h3&gt;

&lt;p&gt;It is a strong free snapshot of one URL. Use it to learn. When you need a named file, a middle score from a few runs, or a report for a client, add a clear report like PafCore. More on that split in &lt;a href="https://pafcore.site/when-pagespeed-insights-is-not-enough" rel="noopener noreferrer"&gt;When PageSpeed Insights is enough (and when it is not)&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is slow WordPress always a hosting problem?
&lt;/h3&gt;

&lt;p&gt;No. Weak hosting can hurt. Large pictures, heavy theme and plugin scripts, fonts, and embeds often cost more than people expect. Measure the page before you buy a bigger plan.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do plugins always make WordPress slow?
&lt;/h3&gt;

&lt;p&gt;Not always. Some plugins add little. Others load big scripts on every page. The honest answer is to measure and see which file costs the most points.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does PafCore replace WordPress speed plugins?
&lt;/h3&gt;

&lt;p&gt;No. Caching and image plugins can help. PafCore measures the live page, shows how far the score moves on its own, and names the slow file when it can. Use both: measure first, then choose a fix.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Try it:&lt;/strong&gt; &lt;a href="https://pafcore.site/#scan" rel="noopener noreferrer"&gt;Check my site&lt;/a&gt; — paste a public WordPress URL. Free report. No signup.&lt;/p&gt;




</description>
    </item>
    <item>
      <title>When PageSpeed Insights is enough (and when it is not)</title>
      <dc:creator>Femi Akinyemi</dc:creator>
      <pubDate>Wed, 09 Sep 2026 10:31:43 +0000</pubDate>
      <link>https://dev.to/femi_akinyemi/when-pagespeed-insights-is-enough-and-when-it-is-not-64g</link>
      <guid>https://dev.to/femi_akinyemi/when-pagespeed-insights-is-enough-and-when-it-is-not-64g</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;PageSpeed Insights is free. It is official. For one URL, right now, it is often the right tool.&lt;/p&gt;

&lt;p&gt;You paste a link. You wait. You get a Lighthouse performance score, lab timings, and field Core Web Vitals when Google has enough Chrome visits. That is a strong snapshot.&lt;/p&gt;

&lt;p&gt;A snapshot is not a watchman.&lt;/p&gt;

&lt;p&gt;This guide is for people who ship websites and still live in PageSpeed tabs. It says when that habit is fine, when it starts to fail you, and what to add without turning every check into a science project.&lt;/p&gt;

&lt;p&gt;By the end you will know:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;when a manual PageSpeed Insights run is enough
&lt;/li&gt;
&lt;li&gt;why one lucky score is a weak proof of a fix
&lt;/li&gt;
&lt;li&gt;when scheduled checks and alerts earn their keep
&lt;/li&gt;
&lt;li&gt;a simple hybrid you can run this week
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Chrome and PageSpeed Insights stay in the mix. I also run a free three run check at &lt;a href="https://pafcore.site" rel="noopener noreferrer"&gt;pafcore.site&lt;/a&gt; when you want the quiet swing and what to fix first without babysitting six tabs.&lt;/p&gt;

&lt;h2&gt;
  
  
  What PageSpeed Insights is good at
&lt;/h2&gt;

&lt;p&gt;Use PageSpeed Insights when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;you are learning Largest Contentful Paint, layout shift, and the performance score
&lt;/li&gt;
&lt;li&gt;you are checking one page before or after a change
&lt;/li&gt;
&lt;li&gt;you manage one or two sites and can afford to click by hand
&lt;/li&gt;
&lt;li&gt;you need field data from the Chrome UX Report on a busy enough URL
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For those jobs, do not add a tool for the sake of a tool. Open the page. Read the wait in seconds. Read the grade. Move on.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where a single run fools you
&lt;/h2&gt;

&lt;p&gt;Even on one site, a single PageSpeed Insights screenshot is a weak proof.&lt;/p&gt;

&lt;p&gt;Lab scores move when the code does not. Machine load, third party tags, and plain luck all show up. I have seen a quiet page score 60, then 51, then 57 with nothing deployed. Nine points of weather.&lt;/p&gt;

&lt;p&gt;So before you celebrate a fix:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Run three quiet checks with no deploy. Learn the gap between best and worst.
&lt;/li&gt;
&lt;li&gt;Ship the change. Run three more.
&lt;/li&gt;
&lt;li&gt;Compare middle scores. Only call it a clear score win when the rise beats that quiet gap.
&lt;/li&gt;
&lt;li&gt;Write the wait you meant to fix in seconds next to the grade.
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That habit works in Chrome DevTools, in PageSpeed Insights, or in a free three run report. Same idea. More than one sample. Seconds and score together.&lt;/p&gt;

&lt;p&gt;I wrote the full quiet gap steps in &lt;a href="https://pafcore.site/why-your-lighthouse-score-changes" rel="noopener noreferrer"&gt;Why your Lighthouse score changes when you did nothing&lt;/a&gt;. Read that when the number moves with no deploy.&lt;/p&gt;

&lt;p&gt;A real wait can also drop while the Lighthouse performance score barely moves. That is the scoring curve, not a broken tool. See &lt;a href="https://pafcore.site/why-faster-barely-moves-your-lighthouse-score" rel="noopener noreferrer"&gt;Why getting faster barely moves your Lighthouse score&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Manual checks fail you twice: at scale, and when you trust one lucky run.&lt;/p&gt;

&lt;h2&gt;
  
  
  When manual checks stop being enough
&lt;/h2&gt;

&lt;p&gt;You have crossed the line when one or more of these are true.&lt;/p&gt;

&lt;h3&gt;
  
  
  You watch more than a handful of pages
&lt;/h3&gt;

&lt;p&gt;Ten sites, a few key URLs each, mobile and desktop: that is a long afternoon of paste, wait, copy, switch. By the time you finish, the first numbers are stale. Miss a week and you have no recent trail when a client asks why search or speed felt worse.&lt;/p&gt;

&lt;h3&gt;
  
  
  A deploy can break speed overnight
&lt;/h3&gt;

&lt;p&gt;A new script, a heavier hero image, a font change. With only weekly PageSpeed Insights checks, you may learn on Friday. Or when the client calls. Scheduled lab checks (daily, or hourly on a few critical pages) shorten that blind spot. An alert should find you, not the other way around.&lt;/p&gt;

&lt;h3&gt;
  
  
  You need history, not only today’s screenshot
&lt;/h3&gt;

&lt;p&gt;PageSpeed Insights does not keep your before and after for you. Trend lines, month to month notes, and “this page got worse after Tuesday’s release” need storage. Screenshots in a folder do not scale.&lt;/p&gt;

&lt;h3&gt;
  
  
  You need budgets and alerts
&lt;/h3&gt;

&lt;p&gt;“LCP should stay under 2.5 seconds on mobile home” is a budget. PageSpeed Insights will not email you when you cross it. A watch with a threshold will.&lt;/p&gt;

&lt;h3&gt;
  
  
  You need something a client can read
&lt;/h3&gt;

&lt;p&gt;Raw PageSpeed output is for builders. Clients want a short story: what got better, what still hurts, what you will do next. That story is easier when history and middle scores already exist.&lt;/p&gt;

&lt;h2&gt;
  
  
  A plain comparison
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Need&lt;/th&gt;
&lt;th&gt;PageSpeed Insights&lt;/th&gt;
&lt;th&gt;Scheduled checks&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;One URL, right now&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mobile and desktop&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lab score and timings&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Field Core Web Vitals when available&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Sometimes (depends on the tool)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Many sites without tab hell&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Daily or hourly runs&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;History and trends&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Budgets and alerts&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Honest before / after (more than one run)&lt;/td&gt;
&lt;td&gt;You must do it by hand&lt;/td&gt;
&lt;td&gt;Still your job to demand it&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Same Lighthouse family of lab maths in many tools. The workflow is what changes. Scheduling does not make a single run more truthful. It makes misses rarer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use both. Split the jobs.
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;PageSpeed Insights or Chrome&lt;/strong&gt; for learning, quick peeks, and one off audits.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Three quiet runs&lt;/strong&gt; (by hand or a free report) whenever you claim a fix worked.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scheduled Watch&lt;/strong&gt; when pages matter every week: home, pricing, checkout, key landing pages. Prove you own the domain. Set a budget. Let email or a webhook tap you when the score or a wait crosses the line.&lt;/p&gt;

&lt;p&gt;That is the hybrid. Not “throw away PageSpeed Insights.” Not “buy a dashboard and stop thinking.”&lt;/p&gt;

&lt;h2&gt;
  
  
  A week one checklist
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;List the pages that would hurt if they got slow (home, money pages, signup).
&lt;/li&gt;
&lt;li&gt;For each, run three quiet mobile checks once. Write the gap and the middle score.
&lt;/li&gt;
&lt;li&gt;Keep using PageSpeed Insights for random questions.
&lt;/li&gt;
&lt;li&gt;Put the money pages on a schedule if you already juggle more than a few sites, or if a bad deploy would cost you a client call.
&lt;/li&gt;
&lt;li&gt;After the next speed fix, compare middle scores to the quiet gap, and write Largest Contentful Paint (or your target wait) in seconds.
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you want the three run spread and “what to fix first” in one paste, use &lt;a href="https://pafcore.site" rel="noopener noreferrer"&gt;pafcore.site&lt;/a&gt;. If you want daily or hourly checks, history, and alerts on pages you own, that is &lt;a href="https://pafcore.site/pro" rel="noopener noreferrer"&gt;Pro Watch&lt;/a&gt; at $19/mo. Credits on the site buy lab checks on a report. Watch runs are separate.&lt;/p&gt;

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

&lt;p&gt;PageSpeed Insights is enough when you need a clear snapshot of one URL. It is not enough when you manage many pages, when you must catch a bad deploy fast, or when you confuse one lucky grade with proof.&lt;/p&gt;

&lt;p&gt;Automate the watch. Keep the honest measure. Talk in seconds and in scores. That mix scales better than living in twenty PageSpeed tabs, and it stays truer than a dashboard that only stores one run a day.&lt;/p&gt;




&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;When is PageSpeed Insights enough?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
One or two sites, learning the metrics, or a one off audit. Once you cannot keep up by hand, or once a missed week would embarrass you, add schedules.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does a scheduled tool use different maths than PageSpeed Insights?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Many lab tools sit on the same Lighthouse style checks. Field Core Web Vitals still come from real Chrome visits over time. Do not expect one lab run to match Search Console the same afternoon.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why three runs if I already have daily monitoring?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Daily monitoring catches surprise drops. Three runs answer “did this fix beat the quiet weather?” You still need both ideas.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I keep PageSpeed Insights for some clients?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Yes. Low stakes pages stay manual. High stakes pages get schedules, budgets, and a quiet gap written down once.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Why your Lighthouse score changes when you did nothing</title>
      <dc:creator>Femi Akinyemi</dc:creator>
      <pubDate>Mon, 07 Sep 2026 06:10:41 +0000</pubDate>
      <link>https://dev.to/femi_akinyemi/why-your-lighthouse-score-changes-when-you-did-nothing-1d8e</link>
      <guid>https://dev.to/femi_akinyemi/why-your-lighthouse-score-changes-when-you-did-nothing-1d8e</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;If you ship websites for a living, you have seen this.&lt;/p&gt;

&lt;p&gt;You change one thing on a page. You open Chrome, run Lighthouse, and the performance score goes up a few points. You take a screenshot. You tell the team the fix worked.&lt;/p&gt;

&lt;p&gt;Later the same day you run the same URL again. No new deploy. The score drops. Sometimes it drops below where you started.&lt;/p&gt;

&lt;p&gt;That is not you failing at your job. Lab scores move even when the code does not. CPU load, network jitter, third party tags, and plain luck all show up in a single run. One number is a sample. It is not a verdict.&lt;/p&gt;

&lt;p&gt;This article gives you a short, repeatable way to read that movement so you stop celebrating noise. By the end you will know:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;why a quiet page can still swing several points &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;how to measure that swing in Chrome in about fifteen minutes  &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;when a &lt;code&gt;fix&lt;/code&gt; is real enough to put in a pull request  &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;how to talk about wins without overselling the score  &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Chrome DevTools is enough for every step. I also built a free three run check at &lt;a href="https://pafcore.site" rel="noopener noreferrer"&gt;pafcore.site&lt;/a&gt; when you want that quiet gap without running Lighthouse by hand. The habit below is the same either way.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the number moves
&lt;/h2&gt;

&lt;p&gt;Lighthouse loads your page in a controlled browser with throttling. That setup is useful because it is harsh and repeatable enough to compare days. It is not a perfect copy of every visitor.&lt;/p&gt;

&lt;p&gt;Small differences stack up:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the machine was busier on one run
&lt;/li&gt;
&lt;li&gt;a third party script answered slower
&lt;/li&gt;
&lt;li&gt;an image raced and won or lost the “largest content” slot
&lt;/li&gt;
&lt;li&gt;the score itself sits on a curve, so the same time change is worth different points at different speeds
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So two runs of an untouched page can land far apart. I have seen a public site score 60, then 51, then 57 with nothing deployed in between. Nine points of weather.&lt;/p&gt;

&lt;p&gt;If you only look at the first run after a deploy, you will misread luck as skill.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you will set up
&lt;/h2&gt;

&lt;p&gt;You need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Chrome
&lt;/li&gt;
&lt;li&gt;the live URL (or a stable preview URL)
&lt;/li&gt;
&lt;li&gt;a note app or the PR description
&lt;/li&gt;
&lt;li&gt;the same Lighthouse mode every time (mobile or desktop). Pick one and keep it
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Turn extensions off, or use a clean window. Do not scroll or click while the audit runs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1. Measure a quiet page
&lt;/h2&gt;

&lt;p&gt;Run Lighthouse three times on the same URL. Do not deploy between runs. Write down the three performance scores.&lt;/p&gt;

&lt;p&gt;Find the highest and the lowest. Subtract. That gap is how far this page already moves when you change nothing.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Run&lt;/th&gt;
&lt;th&gt;Score&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;60&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;51&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;57&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Gap: &lt;strong&gt;9 points&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Some pages only move two or three points. Some move more. You cannot guess your gap. You measure it once per important page (home, pricing, checkout) and you refresh it when the page shape changes a lot.&lt;/p&gt;

&lt;p&gt;Doing those three quiet runs by hand is boring, which is why people skip it. I got tired of skipping it on client work, so I built a free report at &lt;a href="https://pafcore.site" rel="noopener noreferrer"&gt;pafcore.site&lt;/a&gt; that loads the page three times and shows how far the score moves on its own. Use Chrome if you want full control. Use that report if you want the quiet gap filled in for you. Either way, the idea is the same: learn the swing before you celebrate.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2. Ship the change, then measure again
&lt;/h2&gt;

&lt;p&gt;Deploy your fix. Run Lighthouse three more times with the same settings.&lt;/p&gt;

&lt;p&gt;Sort each set of three scores and take the &lt;strong&gt;middle&lt;/strong&gt; one. Compare middle after to middle before.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Clear win:&lt;/strong&gt; the middle score rose by &lt;strong&gt;more than&lt;/strong&gt; the quiet gap.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Not clear yet:&lt;/strong&gt; the rise is smaller than the gap.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;No win:&lt;/strong&gt; the middle score did not rise, or it fell.&lt;/p&gt;

&lt;p&gt;A four point bump on a page with a nine point quiet gap is not a story. It is still inside the swing you already saw.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 3. Write the slow thing in seconds
&lt;/h2&gt;

&lt;p&gt;The score is curved. A real wait can get better while the grade barely moves, especially on a slow page.&lt;/p&gt;

&lt;p&gt;In the same note, track the metric you meant to fix:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Before (middle of 3)&lt;/th&gt;
&lt;th&gt;After (middle of 3)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Performance score&lt;/td&gt;
&lt;td&gt;56&lt;/td&gt;
&lt;td&gt;60&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Biggest picture time&lt;/td&gt;
&lt;td&gt;4.8s&lt;/td&gt;
&lt;td&gt;3.1s&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Now you can say something honest: visitors should feel a clearer first picture, and the score is still noisy. That is better than claiming “we gained four points” when those four points never cleared the quiet gap.&lt;/p&gt;

&lt;p&gt;If both the score and the target time sit inside the quiet swing, do not call it a performance win. Keep the change if the code is cleaner. Leave the victory lap for later.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 4. Do not drown in the tip list
&lt;/h2&gt;

&lt;p&gt;Lighthouse will hand you a long list of opportunities. Most rows are not direct score inputs. The grade comes from a small set of lab metrics (largest content paint, blocking time, layout shift, first content paint, speed index, and similar). Tips about unused script or cache headers can still help people. They only raise the grade if they improve one of those metrics.&lt;/p&gt;

&lt;p&gt;Before you put a tip on the sprint board, answer out loud:&lt;/p&gt;

&lt;p&gt;“If this works, which score metric gets better?”&lt;/p&gt;

&lt;p&gt;No answer means cleanup. Cleanup is fine. Cleanup is not a score promise.&lt;/p&gt;

&lt;p&gt;If two tips are the same heavy image with two labels, fix the image once. Do not add imaginary points from both rows.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 5. Put numbers in the pull request
&lt;/h2&gt;

&lt;p&gt;Paste something like this so review stays calm:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;Lighthouse&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;same&lt;/span&gt; &lt;span class="nx"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;three&lt;/span&gt; &lt;span class="nx"&gt;runs&lt;/span&gt; &lt;span class="nx"&gt;before&lt;/span&gt; &lt;span class="nx"&gt;and&lt;/span&gt; &lt;span class="nx"&gt;three&lt;/span&gt; &lt;span class="nx"&gt;after&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="nx"&gt;Quiet&lt;/span&gt; &lt;span class="nf"&gt;gap &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;max&lt;/span&gt; &lt;span class="nx"&gt;minus&lt;/span&gt; &lt;span class="nx"&gt;min&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;no&lt;/span&gt; &lt;span class="nx"&gt;deploy&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; 
&lt;span class="nx"&gt;Middle&lt;/span&gt; &lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="nx"&gt;before&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
&lt;span class="nx"&gt;Middle&lt;/span&gt; &lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="nx"&gt;after&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
&lt;span class="nx"&gt;Target&lt;/span&gt; &lt;span class="nx"&gt;wait&lt;/span&gt; &lt;span class="nx"&gt;before&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;after&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
&lt;span class="nx"&gt;Clear&lt;/span&gt; &lt;span class="nx"&gt;win&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;yes&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;not&lt;/span&gt; &lt;span class="nx"&gt;sure&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;no&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One screenshot of a lucky run starts arguments. This block ends most of them.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you get from this habit
&lt;/h2&gt;

&lt;p&gt;After you use this a few times you will:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Stop treating a single Lighthouse score as proof.
&lt;/li&gt;
&lt;li&gt;Know your page’s quiet gap, so small bumps stop wasting the team’s week.
&lt;/li&gt;
&lt;li&gt;Separate &lt;code&gt;score went up&lt;/code&gt; from &lt;code&gt;the wait got better,&lt;/code&gt; and report both.
&lt;/li&gt;
&lt;li&gt;Pick tip list work that maps to a real metric, instead of boiling the ocean.
&lt;/li&gt;
&lt;li&gt;Leave a PR trail other people can trust.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That is the value. Not a new theory. A filter for what you already run.&lt;/p&gt;

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

&lt;p&gt;Your Lighthouse score changes when you did nothing because a lab run is noisy. That is expected.&lt;/p&gt;

&lt;p&gt;Measure three quiet runs. Learn the gap. Only call a fix a win when the new middle score beats that gap, and check the wait in seconds too. Treat the long tip list as optional until it names a metric you can move.&lt;/p&gt;

&lt;p&gt;Do this on your important pages once, then again after real releases. You will ship fewer fake wins and sleep better after you post the screenshot.&lt;/p&gt;

&lt;p&gt;I built &lt;a href="https://pafcore.site" rel="noopener noreferrer"&gt;pafcore.site&lt;/a&gt; for the days when I did not want to babysit six Lighthouse runs myself. &lt;/p&gt;

&lt;p&gt;Paste a public URL, get the three run spread, see what to try first by points, and keep the habit from this article either way. &lt;/p&gt;

&lt;p&gt;Chrome alone still works. The site is there when you want the quiet check done in one pass.&lt;/p&gt;

</description>
      <category>analytics</category>
      <category>frontend</category>
      <category>performance</category>
      <category>webdev</category>
    </item>
    <item>
      <title>What AI Still Misses in Production Next.js Apps</title>
      <dc:creator>Femi Akinyemi</dc:creator>
      <pubDate>Mon, 22 Jun 2026 07:10:47 +0000</pubDate>
      <link>https://dev.to/femi_akinyemi/what-ai-still-misses-in-production-nextjs-apps-pcg</link>
      <guid>https://dev.to/femi_akinyemi/what-ai-still-misses-in-production-nextjs-apps-pcg</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;Introduction&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;You ask AI to fix a fetch. It does. Types pass. The component renders. You push.&lt;/p&gt;

&lt;p&gt;Then dev crawls to a stop. Or prod serves a blank page. Or GitHub says conflict on a file you never touched. The model did its job inside the file. It did not see the repo around it.&lt;/p&gt;

&lt;p&gt;That gap is where most Next.js pain actually lives. Not broken JSX. Wrong root folder. Wrong env layer. Wrong deploy model. Stale git ref on the remote.&lt;/p&gt;

&lt;p&gt;This list is the stuff that keeps surviving AI refactors, green CI, and clean local merges.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Next dev watching the whole monorepo
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The problem&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Your app sits inside a bigger repo. There is another lockfile above it. You run &lt;code&gt;next dev&lt;/code&gt;, see a warning about multiple lockfiles, and keep going.&lt;/p&gt;

&lt;p&gt;Compile gets slow. CPU stays high. Sometimes the machine feels stuck for no clear reason. AI will suggest faster imports or smaller components. It will not notice Next is indexing the wrong tree.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The fix&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Pin Turbopack to the app folder in next.config.ts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;path&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;node:path&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;fileURLToPath&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;node:url&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;appRoot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dirname&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;fileURLToPath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;turbopack&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;root&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;appRoot&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;This applies to certain monorepo/workspace setups.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It is not the solution for every slow Next.js dev environment.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If that lockfile warning shows up, treat it as a bug, not noise.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Putting server secrets in &lt;code&gt;NEXT_PUBLIC_*&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The problem&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;AI puts API URLs and tokens in &lt;code&gt;NEXT_PUBLIC_*&lt;/code&gt; because that is what client fetch examples use. Those values ship in the browser bundle. Anyone can read them in the built JS.&lt;/p&gt;

&lt;p&gt;Or the opposite: server route handlers need an upstream URL that only exists as a public var pointing somewhere else. Local dev works with a hack. Prod does not.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The fix&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Split by runtime:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Browser code → &lt;code&gt;NEXT_PUBLIC_*&lt;/code&gt; only&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Route handlers / server code → server env vars (no &lt;code&gt;NEXT_PUBLIC_ prefix&lt;/code&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Upstream URLs and service tokens stay on the server. Client calls your BFF or the public API surface. Never both through one env var.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;3. API address missing or duplicating &lt;code&gt;/api/v1&lt;/code&gt;&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The problem&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One backend expects calls to &lt;code&gt;https://api.example.com&lt;/code&gt;. Another expects &lt;code&gt;https://api.example.com/api/v1&lt;/code&gt;. Your code adds paths on top of the base address. Get it wrong by one segment and every request &lt;code&gt;404s&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This often happens when you copy .env.local from another app in the same repo. AI copies the fetch code correctly. It does not check whether the base address matches this app.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The fix&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Open that app's &lt;code&gt;.env.example&lt;/code&gt;. See exactly how it builds URLs. Match that. Do not assume all apps in one company use the same address format.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;4. Adding server API files to an app that deploys as static &lt;code&gt;HTML&lt;/code&gt;&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The problem&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Some Next apps are built with output: &lt;code&gt;"export"&lt;/code&gt;. That means the output is plain &lt;code&gt;HTML&lt;/code&gt;, &lt;code&gt;CSS&lt;/code&gt;, and &lt;code&gt;JS&lt;/code&gt; files uploaded to static hosting (like S3 or Amplify static). There is no Node server running your app in production.&lt;/p&gt;

&lt;p&gt;You can add files under &lt;code&gt;app/api/&lt;/code&gt; and they may work in local dev. They will not exist after a static build. The hosting serves files, not your API routes.&lt;/p&gt;

&lt;p&gt;AI often suggests "add an API route to hide the token" without checking how the app is deployed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The fix&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you deploy as static files, the browser calls your backend directly and your backend must allow that origin &lt;code&gt;(CORS)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you need a server middle layer to hide tokens, you cannot deploy as a pure static export. You need hosting that runs &lt;code&gt;Next.js&lt;/code&gt; server code.&lt;/p&gt;

&lt;p&gt;Pick one. Mixing both without knowing it is a common break.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;5. Local proxy setup that does not exist in production&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The problem&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In local dev, teams often add a proxy in next.config so calls to &lt;code&gt;/api/v1/...&lt;/code&gt; get forwarded to a real server. Same website address, no cross-origin browser errors. Works great on your machine.&lt;/p&gt;

&lt;p&gt;A static production build does not include that proxy. The browser still calls &lt;code&gt;/api/v1/...&lt;/code&gt; on your static site address. Those requests never reach your backend.&lt;/p&gt;

&lt;p&gt;AI adds the proxy config. It rarely asks how you deploy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The fix&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use different setup for dev and prod:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Dev: proxy in next.config if you want&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Prod: full backend URL in env, &lt;code&gt;CORS&lt;/code&gt; enabled on the backend&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Run next build the same way CI does before you call it done. next dev alone is not enough.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;6. Server-only code imported in a client component&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The problem&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Next has a hard line between server code and client code. Files marked "use client" run in the browser. Things like reading request headers or secret env vars only work on the server.&lt;/p&gt;

&lt;p&gt;One shared &lt;code&gt;lib/api.ts&lt;/code&gt; file often gets imported everywhere. AI merges duplicate files and accidentally puts server code inside a client component. Build fails or you get strange runtime errors.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The fix&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Keep two files:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;One for the browser (simple fetch, public env only)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;One for the server (secret env, used only in app/api routes or server components)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If it reads cookies, headers, or private env, it never goes in a "use client" file.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;7. Login token is valid but for the wrong app&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The problem&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Some apps check two things: is the user logged in, and does their role match this specific product. You paste a login token into .env.local. It is not expired. The app still sends you back to the login page.&lt;/p&gt;

&lt;p&gt;The token belongs to a different dashboard or role. AI tries to fix the redirect logic. The check is working. Your token is for the wrong app.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The fix&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Make sure three things match: the role setting in env, the role inside the token, and what the app's auth guard expects. When testing locally, use a token created for this app specifically.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;8. Fake login still turned on while shipping real auth&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The problem&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Many teams add a dev-only flag that skips real login so they can build UI faster. Useful. Easy to forget about.&lt;/p&gt;

&lt;p&gt;You say auth is done. But callback, token refresh, sign out, and role redirect were never tested with real login. AI sees a user object in state and assumes auth works.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The fix&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use the skip-login flag only for UI work. Before merging: turn it off, log in for real, open a protected page, sign out.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;9. Old dev server still running on the port&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The problem&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You run pnpm dev again without closing the last one. Port &lt;code&gt;3000&lt;/code&gt; is busy. Next starts on &lt;code&gt;3001&lt;/code&gt;. You keep refreshing 3000 and see the wrong app or nothing useful.&lt;/p&gt;

&lt;p&gt;AI will debug your React code. It will not check which process owns the port.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The fix&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="nx"&gt;lsof&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;3000&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Kill the old process. Start fresh. Confirm which port the terminal says before debugging anything else.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;10. No conflict on your machine, conflict on GitHub&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The problem&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You updated your branch with the latest main locally. Merge looks clean. The pull request on GitHub still shows conflicts.&lt;/p&gt;

&lt;p&gt;Your local branch and the copy on GitHub are not the same history anymore. GitHub compares the remote branch to main, not your rebased local copy.&lt;/p&gt;

&lt;p&gt;AI says "pull main again." You already did. On your machine only.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The fix&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After rebasing locally, update GitHub:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;git&lt;/span&gt; &lt;span class="nx"&gt;push&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;force&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="kd"&gt;with&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;lease&lt;/span&gt; &lt;span class="nx"&gt;origin&lt;/span&gt; &lt;span class="nx"&gt;your&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;branch&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Only use this when you intentionally rebased or rewrote branch history.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Check they match:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;git&lt;/span&gt; &lt;span class="nx"&gt;log&lt;/span&gt; &lt;span class="nx"&gt;origin&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;your&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;branch&lt;/span&gt;&lt;span class="p"&gt;..&lt;/span&gt;&lt;span class="nx"&gt;HEAD&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No output means local and remote are in sync.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;11. Expired login token in your env file&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The problem&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For local development, some apps read a login token from .env.local and attach it to server-side API calls. Tokens expire. Handlers return 401 Unauthorized. The UI shows empty data or error states.&lt;/p&gt;

&lt;p&gt;Looks like the API is broken. AI rewrites error handling. The token is just old.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The fix&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Decode the token and check the expiry time. Get a fresh one from a real login. Treat dev tokens like passwords with an expiration date.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;12. Public env vars set after the build, not during it&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The problem&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;NEXT_PUBLIC_&lt;/code&gt; values are written into the JavaScript at build time.&lt;/p&gt;

&lt;p&gt;If you set them in your hosting dashboard after the build already ran, the live site still has the old values baked in.&lt;/p&gt;

&lt;p&gt;Works on your machine with .env.local. Wrong API address or app setting in production.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The fix&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Make sure public env vars exist before next build runs in CI. Some teams write a .env.production file in the build step. Check build logs, not just runtime settings in the host UI.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;13. Copied env from the wrong app in the same repo&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The problem&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Two Next apps in one repo look similar. Same folders, same tools. Different env needs. Copy .env.local from one app into another.&lt;/p&gt;

&lt;p&gt;The shell loads. The first API call or redirect fails. AI assumes env is fine because the file is there.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The fix&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every app has its own .env.example. Start from that file every time.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Env&lt;/code&gt; is per app, not per repo.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;14. Login page and dashboard on the same local port&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The problem&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Login usually lives on one app. The dashboard on another. In local dev that means different ports (for example &lt;code&gt;3001&lt;/code&gt; for login, &lt;code&gt;3000&lt;/code&gt; for dashboard).&lt;/p&gt;

&lt;p&gt;If both URLs in env point to the same port, redirects get confused. Loops, wrong landing page, sign out going nowhere useful.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The fix&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Write down the flow: login address → callback → dashboard address.&lt;/p&gt;

&lt;p&gt;Set &lt;code&gt;env&lt;/code&gt; to match separate apps, even on localhost.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;15. Green code review, nobody ran a production build&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The problem&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;AI fixed the component in the prompt. Types pass. Review looks good. Nobody ran a full production build with real login and a real API call.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The fix&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before merge:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;next dev starts without warnings&lt;/li&gt;
&lt;li&gt;next build passes with the same config CI uses&lt;/li&gt;
&lt;li&gt;One real login (skip-login flag off)&lt;/li&gt;
&lt;li&gt;One API call that returns real data&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;AI is strong inside a single file. It is weak on repo layout, env setup, static vs server deploy, and whether your GitHub branch matches your local branch.&lt;/p&gt;

&lt;p&gt;Those live outside the chat window. Check them yourself and a lot of "random" Next.js bugs stop being random.&lt;/p&gt;

&lt;h2&gt;
  
  
  Need Help With Your Next.js or AWS Project?
&lt;/h2&gt;

&lt;p&gt;Over the last 5+ years, I've helped build and maintain production systems used by businesses across different industries. If you're looking for help with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Next.js applications&lt;/li&gt;
&lt;li&gt;React architecture&lt;/li&gt;
&lt;li&gt;AWS deployments&lt;/li&gt;
&lt;li&gt;AI integrations&lt;/li&gt;
&lt;li&gt;Performance optimization&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;feel free to reach out.&lt;/p&gt;

&lt;p&gt;LinkedIn: &lt;a href="https://www.linkedin.com/in/femi-akinyemi/" rel="noopener noreferrer"&gt;Femi Akinyemi&lt;/a&gt;&lt;br&gt;
DEV: &lt;a href="https://dev.to/femi_akinyemi"&gt;dev.to/femi_akinyemi&lt;/a&gt;&lt;br&gt;
Portfolio: &lt;a href="https://www.femiakinyemi.xyz/" rel="noopener noreferrer"&gt;Femi Akinyemi&lt;/a&gt;&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>react</category>
      <category>frontend</category>
      <category>ai</category>
    </item>
    <item>
      <title>Wedding Memories: The Collaborative Wedding Album!</title>
      <dc:creator>Femi Akinyemi</dc:creator>
      <pubDate>Fri, 11 Oct 2024 15:28:15 +0000</pubDate>
      <link>https://dev.to/femi_akinyemi/wedding-memories-the-collaborative-wedding-album-2em3</link>
      <guid>https://dev.to/femi_akinyemi/wedding-memories-the-collaborative-wedding-album-2em3</guid>
      <description>&lt;h1&gt;
  
  
  Wedding Memories
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/pinata"&gt;The Pinata Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Wedding Memories&lt;/strong&gt; is an app designed to capture, share, and cherish every unforgettable moment from your special day! It allows wedding guests to easily upload photos, creating a collaborative album that captures the essence of the celebration. By using &lt;strong&gt;&lt;a href="https://docs.pinata.cloud/api-reference/files" rel="noopener noreferrer"&gt;Pinata's Files API&lt;/a&gt;&lt;/strong&gt;, the app provides a seamless experience for secure and efficient media uploads and storage.&lt;/p&gt;

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

&lt;p&gt;Check out the live version of the app here: &lt;strong&gt;&lt;a href="https://main.d2kkpc9riv1gcp.amplifyapp.com/" rel="noopener noreferrer"&gt;Wedding Memories&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Upload Section&lt;/strong&gt; - A user-friendly interface for selecting and uploading media files:&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%2F1vuvq6lda3z0u3k0p5la.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%2F1vuvq6lda3z0u3k0p5la.png" alt=" " width="800" height="408"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Gallery View&lt;/strong&gt; - Displays all uploaded memories in a responsive layout:&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%2F9j7ongcgov4g723jnp92.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%2F9j7ongcgov4g723jnp92.png" alt=" " width="799" height="359"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Mobile-Optimized Design&lt;/strong&gt; - Ensures smooth user experience across all devices:&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%2Fpy66u8vt5z5qwui9nla8.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%2Fpy66u8vt5z5qwui9nla8.png" alt=" " width="800" height="715"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Download Options&lt;/strong&gt; - Guests can download their favourite moments to keep memories forever.&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%2Fghtusmmo8mv0r4buk5ry.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%2Fghtusmmo8mv0r4buk5ry.png" alt=" " width="799" height="460"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  My Code
&lt;/h2&gt;

&lt;p&gt;You can explore the full code for this project on GitHub:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/femakin/WeddingMemories" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimg.shields.io%2Fbadge%2FGitHub-Wedding%2520Memories-blue%3Fstyle%3Dfor-the-badge%26logo%3Dgithub" alt="View on GitHub" width="252" height="28"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  More Details
&lt;/h2&gt;

&lt;p&gt;Wedding Memories leverages Pinata’s Files API to build secure and efficient file uploads. Below is a brief breakdown of the integration:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;File Uploads&lt;/strong&gt;: Guests can easily upload images directly from their devices. This is accomplished using the &lt;code&gt;pinata.upload.file&lt;/code&gt;, which uses JWT-based authentication to ensure secure file handling. Once uploaded, the files are securely stored, and their unique identifiers (CIDs) are generated for retrieval.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Local Previews Before Upload&lt;/strong&gt;: To enhance the guest experience, wedding memories generate local previews of images before uploading them. This feature allows guests to confirm their selections and make adjustments, ensuring only their desired image is submitted.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After successful uploads, the files are rendered using the &lt;a href="https://docs.pinata.cloud/sdk/getting-started" rel="noopener noreferrer"&gt;file API&lt;/a&gt;. This guarantees rapid access to the content, providing guests with a seamless experience when viewing shared memories.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Download Feature&lt;/strong&gt;: Guests can now download their favourite photos directly from the app, making it easy to save cherished memories to their devices. The app includes an API route that facilitates the secure downloading of files.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  API Integration Breakdown:
&lt;/h3&gt;

&lt;p&gt;The building includes several key API routes, each designed to handle specific functionalities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;File Upload Endpoint &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This accepts file uploads and stores them using Pinata’s upload function. It then generates a signed URL for easy access to the uploaded file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;NextResponse&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;NextRequest&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;next/server&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;pinata&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../../../../utils/config&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;POST&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NextRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="na"&gt;file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;File&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="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;file&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;File&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;uploadData&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;pinata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;upload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file&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;url&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;pinata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;gateways&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createSignedURL&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;cid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;uploadData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;expires&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3600&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;NextResponse&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="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&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;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;NextResponse&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="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Internal Server Error&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;API Key Generation &lt;code&gt;(/api/key/route.ts)&lt;/code&gt;:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Creates a temporary API key with permissions to pin files to IPFS.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="cm"&gt;/* eslint-disable @typescript-eslint/no-unused-vars */&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;NextResponse&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;next/server&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;pinata&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../../../../utils/config&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dynamic&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;force-dynamic&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;GET&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;uuid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;randomUUID&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;keyData&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;pinata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;keyName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
            &lt;span class="na"&gt;permissions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;endpoints&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="na"&gt;pinning&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="na"&gt;pinFileToIPFS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="na"&gt;maxUses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;NextResponse&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="nx"&gt;keyData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;NextResponse&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;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Error creating API Key:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;List Files &lt;code&gt;(/api/listfiles/route.ts)&lt;/code&gt;:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Retrieves a list of uploaded files from Pinata, allowing users to view all shared content in the gallery&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;NextResponse&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;next/server&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;env&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;process&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dynamic&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;force-dynamic&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;GET&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;RequestInit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GET&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;Authorization&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Bearer &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NEXT_PUBLIC_PINATA_JWT&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;no-cache&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;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://api.pinata.cloud/v3/files&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;NextResponse&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;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Error listing files&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&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;status&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;data&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;NextResponse&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="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="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Error listing files&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="nx"&gt;NextResponse&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;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Error listing files&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Image Proxy &lt;code&gt;(/api/proxy/route.ts)&lt;/code&gt;:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Acts as a proxy for fetching images from external sources, ensuring users can easily access and download their images.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;NextResponse&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="s1"&gt;next/server&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;GET&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&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;searchParams&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;imageUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;searchParams&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="s1"&gt;url&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Get the image URL from the query string&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;imageUrl&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;NextResponse&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;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Image URL is required&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;400&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;imageUrl&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;NextResponse&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;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Failed to fetch image&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&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;status&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;contentType&lt;/span&gt; &lt;span class="o"&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;headers&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="s1"&gt;content-type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/octet-stream&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;imageBuffer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;arrayBuffer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;NextResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;imageBuffer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;contentType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Disposition&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="s1"&gt;attachment; filename="downloaded_image"&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;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Error fetching image:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;NextResponse&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;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Error fetching image&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Signed URL Creation &lt;code&gt;(/api/sign/route.ts)&lt;/code&gt;:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Generates signed URLs for uploaded files.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;NextRequest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;NextResponse&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;next/server&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;pinata&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../../../../utils/config&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dynamic&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;force-dynamic&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;POST&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;NextRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;req&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;mimeType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mime_type&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mimeType&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;video/mp4&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;url&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;pinata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;gateways&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createSignedURL&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;cid&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;cid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;expires&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;7776000&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;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;url&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;pinata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;gateways&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createSignedURL&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;cid&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;cid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;expires&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;7776000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;optimizeImage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;webp&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;fit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;contain&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;quality&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;90&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;dpr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;sharpen&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

      &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;NextResponse&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="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;NextResponse&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;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Error creating signed URL:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;The app is built with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Pinata&lt;/strong&gt;: File API&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Frontend&lt;/strong&gt;: React, Next.js, Framer Motion&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Styling&lt;/strong&gt;: Tailwind CSS for responsive, beautiful layouts.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Hosting&lt;/strong&gt;: Amplify for deployment.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Weddings are joyous occasions filled with love, laughter, and countless memorable moments. Capturing these precious memories is essential, and with the &lt;strong&gt;&lt;a href=""&gt;Wedding Memories&lt;/a&gt;&lt;/strong&gt; app, it's now easier than ever! &lt;/p&gt;

&lt;p&gt;This application allows every guest to take lovely pictures on the event day and share them seamlessly, ensuring that no moment is missed and everyone has access to the collective memories of the celebration.&lt;/p&gt;

&lt;p&gt;The app harnesses the power of &lt;strong&gt;&lt;a href="https://docs.pinata.cloud/sdk/getting-started" rel="noopener noreferrer"&gt;Pinata's Files API&lt;/a&gt;&lt;/strong&gt; to provide a secure and efficient way for guests to upload and share their photos and videos, creating a collaborative album that beautifully encapsulates the essence of the day.&lt;/p&gt;

&lt;p&gt;For more details on how the app integrates with Pinata and to explore its capabilities, please refer to the &lt;a href="https://main.d2kkpc9riv1gcp.amplifyapp.com/" rel="noopener noreferrer"&gt;Pinata documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thank you.&lt;/p&gt;




</description>
      <category>devchallenge</category>
      <category>pinatachallenge</category>
      <category>webdev</category>
      <category>api</category>
    </item>
    <item>
      <title>How to Upload Files to Amazon S3 with React and AWS SDK</title>
      <dc:creator>Femi Akinyemi</dc:creator>
      <pubDate>Mon, 04 Mar 2024 15:54:14 +0000</pubDate>
      <link>https://dev.to/aws-builders/how-to-upload-files-to-amazon-s3-with-react-and-aws-sdk-b0n</link>
      <guid>https://dev.to/aws-builders/how-to-upload-files-to-amazon-s3-with-react-and-aws-sdk-b0n</guid>
      <description>&lt;h1&gt;
  
  
  INTRODUCTION
&lt;/h1&gt;

&lt;p&gt;Have you ever needed to upload files from your React application to the cloud?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://aws.amazon.com/s3/" rel="noopener noreferrer"&gt;Amazon S3 (Simple Storage Service)&lt;/a&gt; provides a robust and scalable solution for storing and managing various file types. &lt;/p&gt;

&lt;p&gt;Using the &lt;a href="https://www.npmjs.com/package/aws-sdk" rel="noopener noreferrer"&gt;AWS SDK&lt;/a&gt;, this article shows how to build a &lt;a href="https://react.dev/" rel="noopener noreferrer"&gt;React&lt;/a&gt; application that allows users to upload files to S3. &lt;/p&gt;

&lt;p&gt;In the article, you'll learn how to handle file selection, validate file types, and handle the upload process with error handling. &lt;/p&gt;

&lt;p&gt;By the end, you'll have a basic understanding of integrating file uploads to S3 with React and AWS.&lt;/p&gt;

&lt;h1&gt;
  
  
  Prerequisite:
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Basic understanding of React and JavaScript.&lt;/li&gt;
&lt;li&gt;An AWS account and access credentials to configure the S3 connection.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Getting Started
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Creating S3 Bucket
&lt;/h2&gt;

&lt;p&gt;The first thing to do is start by creating an S3 bucket. Log in to the AWS S3 console and follow the instructions to create a new bucket, as shown in the image below.&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%2F8jjca9mzxy0834s4a6hm.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%2F8jjca9mzxy0834s4a6hm.png" alt="Create Bucket" width="799" height="189"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Making the files publicly accessible
&lt;/h2&gt;

&lt;p&gt;Next is to edit the bucket policy to make the file publicly accessible. &lt;/p&gt;

&lt;p&gt;Here's how:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open the bucket: Go to the AWS S3 console and navigate to your specific bucket.&lt;/li&gt;
&lt;li&gt;Access permissions: Click on the 'Permissions' tab.&lt;/li&gt;
&lt;li&gt;Edit policy: Locate the 'Bucket policy' section and click the 'Edit Policy' button.&lt;/li&gt;
&lt;li&gt;Paste JSON code: Copy and paste the following JSON code into the policy editor.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Version&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;2012-10-17&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;Statement&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Sid&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;PublicListGet&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;Effect&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;Allow&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;Principal&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;*&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;Action&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;s3:List*&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;s3:Get*&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;Resource&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;arn:aws:s3:::YOUR_BUCKET_NAME&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;arn:aws:s3:::YOUR_BUCKET_NAME/*&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Save changes: Review the policy and click 'Save'.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The policy above makes all objects in the S3 bucket named &lt;em&gt;YOUR_BUCKET_NAME&lt;/em&gt; publicly accessible. Anyone online can list and download all files in the bucket and its subfolders. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The policy should be used cautiously as it can be a security risk.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Editing CORS Policy
&lt;/h2&gt;

&lt;p&gt;Now, you must enable &lt;strong&gt;Cross-origin resource sharing (CORS)&lt;/strong&gt;. &lt;br&gt;
The CORS configuration, written in JSON, allows clients to access resources in a different domain from applications within the same domain.&lt;/p&gt;

&lt;p&gt;Scroll down a bit more, and you will see a section where you can edit CORS settings. &lt;/p&gt;

&lt;p&gt;Paste the below JSON into it to enable the upload of files from the front end, or you will receive a CORS error while uploading files.&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%2Fao4xc1vpoovglxsk5ghd.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%2Fao4xc1vpoovglxsk5ghd.png" alt="Editing CORS Policy" width="799" height="189"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="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;AllowedHeaders&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;*&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;AllowedMethods&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;PUT&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;POST&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;DELETE&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;GET&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;AllowedOrigins&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;*&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;ExposeHeaders&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Uploading files to your AWS S3 bucket is now possible. &lt;/p&gt;

&lt;p&gt;Next, we'll talk about the front end.&lt;/p&gt;

&lt;p&gt;Run the command below to Scaffold your react application.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="nx"&gt;npx&lt;/span&gt; &lt;span class="nx"&gt;create&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;react&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="nx"&gt;filestorage&lt;/span&gt;
&lt;span class="nx"&gt;cd&lt;/span&gt; &lt;span class="nx"&gt;filestorage&lt;/span&gt;
&lt;span class="nx"&gt;npm&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt;

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Installing AWS SDK for JavaScript
&lt;/h2&gt;

&lt;p&gt;You must install the AWS SDK for JavaScript, allowing your React JS application to communicate with S3.&lt;/p&gt;

&lt;p&gt;Run the command below to install AWS SDK&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;npm&lt;/span&gt; &lt;span class="nx"&gt;install&lt;/span&gt; &lt;span class="nx"&gt;aws&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;sdk&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next is to replace the default code in the App.js file with the code below&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&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="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// Uncomment one of the following import options:&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;AWS&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;aws-sdk&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Import entire SDK (optional)&lt;/span&gt;
&lt;span class="c1"&gt;// import AWS from 'aws-sdk/global'; // Import global AWS namespace (recommended)&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;S3&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;aws-sdk/clients/s3&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Import only the S3 client&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./App.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setFile&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;uploading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setUploading&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;allowedTypes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;image/jpeg&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="s1"&gt;image/png&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="s1"&gt;application/pdf&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="s1"&gt;video/mp4&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="s1"&gt;video/quicktime&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="s1"&gt;audio/mpeg&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="s1"&gt;audio/wav&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="c1"&gt;// Add more supported types as needed&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;handleFileChange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;selectedFile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&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="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;allowedTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selectedFile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;setFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selectedFile&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Invalid file type. Only images and PDFs are allowed.&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;uploadFile&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="nf"&gt;setUploading&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;S3_BUCKET&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;your_bucket_name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Replace with your bucket name&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;REGION&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;your_region&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Replace with your region&lt;/span&gt;

    &lt;span class="nx"&gt;AWS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;accessKeyId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;your_accesskeyID&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;secretAccessKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;your_secretAccessKey&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="nx"&gt;s3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;S3&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;Bucket&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;S3_BUCKET&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;region&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;REGION&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;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;Bucket&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;S3_BUCKET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;upload&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;s3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;putObject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;upload&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nf"&gt;setUploading&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nf"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;File uploaded 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="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nf"&gt;setUploading&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nf"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Error uploading file: &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Inform user about the error&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;file&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;required&lt;/span&gt; &lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleFileChange&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;uploadFile&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;uploading&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Uploading...&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="s1"&gt;Upload File&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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


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

&lt;/div&gt;



&lt;p&gt;The React code above creates a simple file uploader app. Users can select a file that is uploaded to an Amazon S3 bucket. &lt;/p&gt;

&lt;p&gt;Here's a brief breakdown:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;State Management:&lt;/strong&gt; It uses React's useState hook to manage the selected file and uploading state.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Allowed File Types:&lt;/strong&gt; Defines an array of allowed file types.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;File Change Handler:&lt;/strong&gt; When a file is selected, it checks if the file type is allowed and updates the state with the selected file.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Upload Function:&lt;/strong&gt; Constructs S3 parameters and uploads the file to the specified S3 bucket. It handles success and error cases, providing feedback to the user.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;User Interface:&lt;/strong&gt; Provides a file input field and a button for uploading—the button text changes based on the uploading state.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;AWS SDK:&lt;/strong&gt; Imports necessary modules from the AWS SDK to interact with S3 and configures it with credentials and region.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The code offers a basic file uploading functionality to S3 from a React app.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;You've successfully uploaded a file to your S3 bucket with these steps! You can consult the documentation for tailored options that suit your specific requirements.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>react</category>
      <category>s3</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Build a simple project management app with Neon, PostgREST, and DigitalOcean</title>
      <dc:creator>Femi Akinyemi</dc:creator>
      <pubDate>Tue, 27 Feb 2024 16:29:41 +0000</pubDate>
      <link>https://dev.to/hackmamba/build-a-simple-project-management-app-with-neon-postgrest-and-digitalocean-3iid</link>
      <guid>https://dev.to/hackmamba/build-a-simple-project-management-app-with-neon-postgrest-and-digitalocean-3iid</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://neon.tech/?utm_source=hackmamba&amp;amp;utm_medium=blog&amp;amp;utm_id=HMBcommunity" rel="noopener noreferrer"&gt;Neon&lt;/a&gt; &lt;a href="https://neon.tech/?utm_source=hackmamba&amp;amp;utm_medium=blog&amp;amp;utm_id=HMBcommunity" rel="noopener noreferrer"&gt;s&lt;/a&gt;&lt;a href="https://neon.tech/?ref=hm" rel="noopener noreferrer"&gt;erverless Postgres&lt;/a&gt; stands out in the world of databases. It provides a fully managed service for PostgreSQL with unique features like &lt;a href="https://neon.tech/docs/introduction/autoscaling?ref=hm" rel="noopener noreferrer"&gt;autoscaling&lt;/a&gt;, &lt;a href="https://neon.tech/docs/introduction/branching?ref=hm" rel="noopener noreferrer"&gt;branching&lt;/a&gt;, and a great serverless experience. Its architecture makes Neon serverless Postgres different from how users set up Postgres databases by separating storage and compute.&lt;/p&gt;

&lt;p&gt;In this guide, we'll leverage the strengths of Neon serverless Postgres to establish a &lt;a href="https://postgrest.org/en/stable/?utm_source=hackmamba&amp;amp;utm_medium=blog&amp;amp;utm_id=HMBcommunity" rel="noopener noreferrer"&gt;PostgREST&lt;/a&gt; API on &lt;a href="https://www.digitalocean.com/" rel="noopener noreferrer"&gt;DigitalOcean&lt;/a&gt;. With PostgREST, a PostgreSQL database is turned into a RESTful API.&lt;/p&gt;

&lt;p&gt;As a practical illustration, we’ll walk through creating a mini project management application with complete create, read, update, and delete (CRUD) functionality. This application will allow users to create new projects, view existing details, update information, and delete projects as needed. &lt;/p&gt;

&lt;p&gt;Ultimately, you’ll have a fully functional PostgREST API powered by Neon serverless Postgres, seamlessly incorporated into your DigitalOcean environment.&lt;/p&gt;

&lt;h1&gt;
  
  
  Prerequisites
&lt;/h1&gt;

&lt;p&gt;To fully grasp the concepts presented in this tutorial, you’ll need the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://console.neon.tech/sign_in?ref=?utm_source=hackmamba&amp;amp;utm_medium=blog&amp;amp;utm_id=HMBcommunity" rel="noopener noreferrer"&gt;A Neon account&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cloud.digitalocean.com/registrations/new?utm_source=hackmamba&amp;amp;utm_medium=blog&amp;amp;utm_id=HMBcommunity" rel="noopener noreferrer"&gt;A DigitalOcean account&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;A basic understanding of PostgreSQL and REST APIs&lt;/li&gt;
&lt;li&gt;Node.js installed on your local machine&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Create a Neon project
&lt;/h1&gt;

&lt;p&gt;To set up a Neon project, let’s begin by &lt;a href="https://console.neon.tech/sign_in?ref=hm" rel="noopener noreferrer"&gt;registering for an account&lt;/a&gt;, assuming you don't have one already. With that done, we’ll create a new project by selecting a &lt;strong&gt;Project Name&lt;/strong&gt;. We will use (Project Management), &lt;strong&gt;Database name&lt;/strong&gt; (&lt;code&gt;managementdata&lt;/code&gt;), and &lt;strong&gt;Postgres version&lt;/strong&gt;. For this demonstration, we’ll opt for 16 as the Postgres version and choose the region closest to where we would like to deploy our app.&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%2Fec6lasih9wwqzrnhz0sm.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%2Fec6lasih9wwqzrnhz0sm.png" alt="project creation" width="800" height="456"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Upon successfully creating the project, we will get a connection string for connecting to our database. &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%2Fnggp1seqi36sdtdzaxvi.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%2Fnggp1seqi36sdtdzaxvi.png" alt="Connection string" width="800" height="494"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Project directory
&lt;/h2&gt;

&lt;p&gt;To organize our project files and resources, let's create a new project directory using the following terminal command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="nx"&gt;mkdir&lt;/span&gt; &lt;span class="nx"&gt;neonprojectappfolder&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Loading demo data into the database
&lt;/h2&gt;

&lt;p&gt;With the project directory in place, follow these steps to load the demo data into the database.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To connect to our database, we will use the connection string provided by Neon and run it in the terminal:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="nx"&gt;psql&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;postgresql://xxx:xxxx@ep-xxx-xxx-01196450.us-east-2.aws.neon.tech/xxx?sslmode=require&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The command connects to the database using the provided connection string.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; Now that we’re connected to the database, let’s upload our demo data by running the command below in the terminal:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="nx"&gt;psql&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;postgresql://xxx:xxxx@ep-xxx-xxx-01196450.us-east-2.aws.neon.tech/xxx?sslmode=require &amp;lt; projects.sql
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The demo data (projects.sql) can be downloaded &lt;a href="https://gist.github.com/femakin/f1ecfa87c607744a65b03a6a1c11271a?utm_source=hackmamba&amp;amp;utm_medium=blog&amp;amp;utm_id=HMBcommunity" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The demo data must be downloaded in our project directory before running the command above.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Upon successfully loading demo data into the database, we’ll see a response like the image below:&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%2F3gkniset8zudqnmwzm03.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%2F3gkniset8zudqnmwzm03.png" alt="Loading Data RESPONSE" width="793" height="44"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The output &lt;code&gt;CREATE SEQUENCE&lt;/code&gt;, &lt;code&gt;CREATE TABLE&lt;/code&gt;, and &lt;code&gt;INSERT 0 5&lt;/code&gt; indicate that the sequence, the table, and five rows were inserted into the table, respectively.&lt;/p&gt;

&lt;p&gt;Next, we verify the demo data is present using the following steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First, connect to the database again by running the command below:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="nx"&gt;psql&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;postgresql://xxx:xxxx@ep-xxx-xxx-01196450.us-east-2.aws.neon.tech/xxx?sslmode=require&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(Just a note that we’re connecting to the database again because we exited the database when we loaded the demo data into the database.)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Now, let us run the command below in our terminal:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="nx"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;FROM&lt;/span&gt; &lt;span class="nx"&gt;projects&lt;/span&gt; &lt;span class="nx"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The SQL command &lt;code&gt;SELECT * FROM projects LIMIT 1&lt;/code&gt; retrieves data from the "projects" table.&lt;/p&gt;

&lt;p&gt;We should get a response like the one in the image below.&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%2Fc2ha8fd346isseqk9dg3.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%2Fc2ha8fd346isseqk9dg3.png" alt="Data response" width="798" height="150"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As a result, our demo data has been successfully uploaded to our database.&lt;/p&gt;

&lt;h1&gt;
  
  
  PostgREST setup
&lt;/h1&gt;

&lt;p&gt;Now that we have set up our database, the next step involves setting up PostgREST. First, we install PostgREST by following this installation &lt;a href="https://postgrest.org/en/stable/explanations/install.html#install" rel="noopener noreferrer"&gt;guide&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;After a successful installation, we can confirm everything works perfectly by typing &lt;code&gt;postgrest -e&lt;/code&gt; in the terminal. We should see a response similar to the image below, indicating a successful operation.&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%2Fftdtqafpm4bp7quc3uq0.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%2Fftdtqafpm4bp7quc3uq0.png" alt="PostgREST confirmation" width="800" height="540"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Granting CRUD access to a database user
&lt;/h2&gt;

&lt;p&gt;Now, we can connect to the database using the connection string above.&lt;/p&gt;

&lt;p&gt;(We’re connecting again because checking the PostgREST installation disconnected us from the database.)&lt;/p&gt;

&lt;p&gt;After a successful connection, execute the command below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="nx"&gt;GRANT&lt;/span&gt; &lt;span class="nx"&gt;SELECT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;INSERT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;UPDATE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;DELETE&lt;/span&gt; &lt;span class="nx"&gt;ON&lt;/span&gt; &lt;span class="nx"&gt;TABLE&lt;/span&gt; &lt;span class="kr"&gt;public&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;projects&lt;/span&gt; &lt;span class="nx"&gt;TO&lt;/span&gt; &lt;span class="nx"&gt;femakin&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The command grants &lt;code&gt;femakin&lt;/code&gt; user permissions for &lt;code&gt;SELECT&lt;/code&gt;, &lt;code&gt;INSERT&lt;/code&gt;, &lt;code&gt;UPDATE&lt;/code&gt;, and &lt;code&gt;DELETE&lt;/code&gt; operations (CRUD) on the projects table in the public schema.&lt;/p&gt;

&lt;h2&gt;
  
  
  PostgREST connection setup
&lt;/h2&gt;

&lt;p&gt;The next step is to establish a PostgREST connection. To do this, exit the database terminal by typing &lt;code&gt;\q&lt;/code&gt; and then enter the following command: &lt;code&gt;vi projects.config&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The command &lt;code&gt;vi projects.config&lt;/code&gt; opens the &lt;code&gt;projects.config&lt;/code&gt; file using the vi text editor.&lt;/p&gt;

&lt;p&gt;We then edit the &lt;code&gt;projects.config&lt;/code&gt; file by pasting the command below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;uri&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;psql&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;postgresql://xxx:xxxx@ep-xxx-xxx-01196450.us-east-2.aws.neon.tech/xxx?sslmode=require&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;schema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;public&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;anon&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;role&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;femakin&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This configuration specifies a PostgreSQL database connection string URI with credentials and connection details. It also defines the default database schema as &lt;code&gt;public&lt;/code&gt; and the anonymous role as &lt;code&gt;femakin&lt;/code&gt; for authentication purposes.&lt;/p&gt;

&lt;p&gt;To ensure the proper setup of the PostgREST connection, we can run &lt;code&gt;postgrest projects.config&lt;/code&gt; in the terminal. This command should yield a response similar to the image below.&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%2Fzbcjbig5n8aixx7nnjg6.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%2Fzbcjbig5n8aixx7nnjg6.png" alt="PostgREST setup" width="800" height="133"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing the API routes
&lt;/h2&gt;

&lt;p&gt;Now, let us employ a tool such as Postman to conduct tests. In the browser, navigate to the URL &lt;code&gt;localhost:3000/projects&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The connection is working if we find something like this in the browser.&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%2F9iz40hdc0pd431f2y1kx.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%2F9iz40hdc0pd431f2y1kx.png" alt="API response" width="798" height="132"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Otherwise, we must review all the steps and ensure everything is present.&lt;/p&gt;

&lt;h1&gt;
  
  
  Bootstrapping VueJS application
&lt;/h1&gt;

&lt;p&gt;The quickest approach to get started with our VueJS application is to clone this &lt;a href="https://github.com/femakin/Neo-Demo-PostgREST-DigitalOcean-App?utm_source=hackmamba&amp;amp;utm_medium=blog&amp;amp;utm_id=HMBcommunity" rel="noopener noreferrer"&gt;Git&lt;/a&gt;&lt;a href="https://github.com/femakin/Neo-Demo-PostgREST-DigitalOcean-App?utm_source=hackmamba&amp;amp;utm_medium=blog&amp;amp;utm_id=HMBcommunity" rel="noopener noreferrer"&gt;H&lt;/a&gt;&lt;a href="https://github.com/femakin/Neo-Demo-PostgREST-DigitalOcean-App?utm_source=hackmamba&amp;amp;utm_medium=blog&amp;amp;utm_id=HMBcommunity" rel="noopener noreferrer"&gt;ub repository&lt;/a&gt;&lt;a href="https://github.com/femakin/Neo-Demo-PostgREST-DigitalOcean-App?utm_source=hackmamba&amp;amp;utm_medium=blog&amp;amp;utm_id=HMBcommunity" rel="noopener noreferrer"&gt;:&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="nx"&gt;git&lt;/span&gt; &lt;span class="nx"&gt;clone&lt;/span&gt; &lt;span class="nx"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//github.com/femakin/Neo-Demo-PostgREST-DigitalOcean-App&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Follow the instructions in the README file: Run &lt;code&gt;npm install&lt;/code&gt; to install dependencies and &lt;code&gt;npm run dev&lt;/code&gt; to start the application. &lt;/p&gt;

&lt;p&gt;The application will appear like this in the browser:&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%2Fr7zhvwg9phnus7zgc4ut.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%2Fr7zhvwg9phnus7zgc4ut.png" alt="Home screen" width="800" height="503"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The code in the &lt;code&gt;src/App.vue&lt;/code&gt; is a project management app using VueJS. It handles project data, loading status, and user interactions. It fetches project data and lets users view, add, update, and delete projects. The focus is on simplicity for managing projects in a web app.&lt;/p&gt;

&lt;h1&gt;
  
  
  Deploying to Digital Ocean
&lt;/h1&gt;

&lt;p&gt;Thus far, we’ve created our database, set up PostgREST, and got our mini-application running in VueJS. Now, we need to deploy everything to DigitalOcean. To do this, &lt;a href="https://cloud.digitalocean.com/login?utm_source=hackmamba&amp;amp;utm_medium=blog&amp;amp;utm_id=HMBcommunity" rel="noopener noreferrer"&gt;log into&lt;/a&gt; the DigitalOcean dashboard and create a Droplet by following this &lt;a href="https://docs.digitalocean.com/products/droplets/how-to/create/?utm_source=hackmamba&amp;amp;utm_medium=blog&amp;amp;utm_id=HMBcommunity" rel="noopener noreferrer"&gt;guide&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;DigitalOcean Droplets are Linux-based virtual machines (VMs) that operate on virtualized hardware.&lt;/p&gt;

&lt;p&gt;Now, let’s access our droplet. First, copy the created droplet's &lt;code&gt;IP&lt;/code&gt; address, as shown in the image below, and then use it to &lt;code&gt;SSH&lt;/code&gt; into the droplet.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: Keep this IP address handy; we’ll need it for future steps.&lt;/p&gt;
&lt;/blockquote&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%2F7mhmeui04vux3xsw42q9.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%2F7mhmeui04vux3xsw42q9.png" alt="Droplet IP" width="800" height="240"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, log into the droplet by using the copied droplet's &lt;code&gt;IP&lt;/code&gt; and running the command below in the terminal:&lt;/p&gt;

&lt;p&gt;Next, log into the droplet by using the copied droplet's &lt;code&gt;IP&lt;/code&gt; and running the command below in the terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="nx"&gt;ssh&lt;/span&gt; &lt;span class="nx"&gt;root&lt;/span&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;copied_droplet_IP&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will prompt us to enter a passphrase for the key.&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%2F0ubqmdtaliud93bag5ku.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%2F0ubqmdtaliud93bag5ku.png" alt="SSH connection" width="800" height="520"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, we will update the &lt;code&gt;apt cache&lt;/code&gt; to get the latest packages by running the below command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="nx"&gt;sudo&lt;/span&gt; &lt;span class="nx"&gt;apt&lt;/span&gt; &lt;span class="nx"&gt;update&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fuoryv16fr72w2u6dt7w6.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%2Fuoryv16fr72w2u6dt7w6.png" alt="Cache update" width="799" height="172"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A runtime library, an essential component of the PostgreSQL database system, must be installed. This library is a connection and communication interface for PostgreSQL database servers.&lt;/p&gt;

&lt;p&gt;Let’s run the following command in the terminal to install the PostgreSQL runtime library, &lt;code&gt;libpq5&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="nx"&gt;sudo&lt;/span&gt; &lt;span class="nx"&gt;apt&lt;/span&gt; &lt;span class="nx"&gt;install&lt;/span&gt; &lt;span class="nx"&gt;libpq5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will ensure that the necessary runtime components for PostgreSQL are installed on the system.&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%2Fq4e76z9ehe1xnepcy02x.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%2Fq4e76z9ehe1xnepcy02x.png" alt="libpq5" width="800" height="459"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, we’ll install PostgREST from the release page available &lt;a href="https://github.com/PostgREST/postgrest/releases/tag/v11.2.0?utm_source=hackmamba&amp;amp;utm_medium=blog&amp;amp;utm_id=HMBcommunity" rel="noopener noreferrer"&gt;here&lt;/a&gt;. Choose a version compatible with your operating system; for example, we will install &lt;code&gt;postgrest-v11.2.0-linux-static-x64.tar.xz&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="nx"&gt;wget&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://github.com/PostgREST/postgrest/releases/download/v11.2.0/postgrest-v11.2.0-linux-static-x64.tar.xz&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fbaip4unlefyi6qaokpl6.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%2Fbaip4unlefyi6qaokpl6.png" alt="Downloading PostgREST" width="800" height="329"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next is to extract the compressed file to obtain the executable. Run the command below in the terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="nx"&gt;root&lt;/span&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;project&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;management&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nx"&gt;tar&lt;/span&gt; &lt;span class="nx"&gt;vxf&lt;/span&gt; &lt;span class="nx"&gt;postgrest&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;v11&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mf"&gt;2.1&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;linux&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="kd"&gt;static&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;x64&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;xz&lt;/span&gt;
    &lt;span class="nx"&gt;postgrest&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To ensure everything works, let's run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;postgrest&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We should expect a response similar to the image below.&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%2F1u7bz05v4enhyczrepg3.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%2F1u7bz05v4enhyczrepg3.png" alt="Starting PostgREST" width="800" height="366"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuring PostgREST on Droplet
&lt;/h2&gt;

&lt;p&gt;Let us configure PostgREST by following the steps below.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; Move PostgREST to &lt;code&gt;usr/bin&lt;/code&gt; by executing the following command:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="nx"&gt;sudo&lt;/span&gt; &lt;span class="nx"&gt;mv&lt;/span&gt; &lt;span class="nx"&gt;postgrest&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;usr&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;bin&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt; Navigate to &lt;code&gt;/usr/bin&lt;/code&gt; using the command
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="nx"&gt;cd&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;usr&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;bin&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt; Confirm that everything is in order by running
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;postgrest&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt; Now, create a directory using the command
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="nx"&gt;mkdir&lt;/span&gt; &lt;span class="nx"&gt;projectsmanagement&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's return to our local machine within the project directory and copy the config file using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="nx"&gt;cat&lt;/span&gt; &lt;span class="nx"&gt;projects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We previously created the config file in the section above. We’ll see a configuration similar to the one below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;uri&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;psql&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;postgresql://xxx:xxxx@ep-xxx-xxx-01196450.us-east-2.aws.neon.tech/xxx?sslmode=require&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;schema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;public&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;anon&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;role&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;femakin&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, return to our droplet and create a new config using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="nx"&gt;vi&lt;/span&gt; &lt;span class="nx"&gt;projects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Paste the copied &lt;code&gt;projects.config&lt;/code&gt;, and save the file.&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%2Fel85bp045qtzz1a7zpdi.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%2Fel85bp045qtzz1a7zpdi.png" alt="projects.config" width="798" height="167"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, we can connect to our database using &lt;code&gt;postgrest postgrest.config&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You should now see a response stating that the connection is successful, as shown in the image below:&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%2Fy4hen1b92vaoc428s63s.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%2Fy4hen1b92vaoc428s63s.png" alt="Connecting to database" width="798" height="167"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, we can test the API using the command &lt;code&gt;curl localhost:3000/projects&lt;/code&gt;, and observe a response from our database, like the illustration below.&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%2F4rheon8ixoizrc6ejng0.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%2F4rheon8ixoizrc6ejng0.png" alt="Response" width="800" height="669"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating systemd
&lt;/h2&gt;

&lt;p&gt;Now, let's create a system service for a PostgREST. We need to go back to PostgREST documentation &lt;a href="https://postgrest.org/en/stable/integrations/systemd.html?highlight=daemonizing?utm_source=hackmamba&amp;amp;utm_medium=blog&amp;amp;utm_id=HMBcommunity" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

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

&lt;p&gt;We can now go back to our droplet and create the system file using the command below:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;vi /etc/systemd/system/postgrest.service&lt;/code&gt; and paste the code below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;Unit&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;Description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;REST&lt;/span&gt; &lt;span class="nx"&gt;API&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;any&lt;/span&gt; &lt;span class="nx"&gt;PostgreSQL&lt;/span&gt; &lt;span class="nx"&gt;database&lt;/span&gt;
    &lt;span class="nx"&gt;After&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;postgresql&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;service&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;Service&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;ExecStart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sr"&gt;/usr/&lt;/span&gt;&lt;span class="nx"&gt;bin&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;postgrest&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;usr&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;bin&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;postgrest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;
    &lt;span class="nx"&gt;ExecReload&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sr"&gt;/bin/&lt;/span&gt;&lt;span class="nx"&gt;kill&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;SIGUSR1&lt;/span&gt; &lt;span class="nx"&gt;$MAINPID&lt;/span&gt;
    &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;nobody&lt;/span&gt;
    &lt;span class="nx"&gt;Group&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;nogroup&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;Install&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;WantedBy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;multi&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt; 

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

&lt;/div&gt;



&lt;p&gt;Here, we’ll reload, start, and check the status of the &lt;code&gt;systemd&lt;/code&gt; using the command below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;     &lt;span class="nx"&gt;sudo&lt;/span&gt; &lt;span class="nx"&gt;systemctl&lt;/span&gt; &lt;span class="nx"&gt;daemon&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;reload&lt;/span&gt;
     &lt;span class="nx"&gt;sudo&lt;/span&gt; &lt;span class="nx"&gt;systemctl&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt; &lt;span class="nx"&gt;postgrest&lt;/span&gt;
     &lt;span class="nx"&gt;sudo&lt;/span&gt; &lt;span class="nx"&gt;systemctl&lt;/span&gt; &lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="nx"&gt;postgrest&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2F846ktxeh8r4r0h4nind8.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%2F846ktxeh8r4r0h4nind8.png" alt="Reload systemd" width="800" height="169"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Testing the API using &lt;code&gt;curl localhost:3000/projects&lt;/code&gt; gives us our expected response, as shown below:&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%2Fyz1j4wlo2qp8m4vns95y.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%2Fyz1j4wlo2qp8m4vns95y.png" alt="curl response" width="800" height="169"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Uploading the Vue app into Droplet
&lt;/h2&gt;

&lt;p&gt;It's time to upload our project management application into the droplet. Return to your local machine to upload the application into the droplet and run &lt;code&gt;npm run build&lt;/code&gt; inside the project directory.&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%2Fxsf6ubt4nqvos6f15c8x.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%2Fxsf6ubt4nqvos6f15c8x.png" alt="App build" width="800" height="604"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that we have our production Vue App, we can copy it into the droplet using the command below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="nx"&gt;scp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt; &lt;span class="nx"&gt;dist&lt;/span&gt; &lt;span class="nx"&gt;root&lt;/span&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;copied_droplet_IP&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;usr&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;bin&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;vueapp&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next is to install a web server to serve the files.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="nx"&gt;sudo&lt;/span&gt; &lt;span class="nx"&gt;apt&lt;/span&gt; &lt;span class="nx"&gt;install&lt;/span&gt; &lt;span class="nx"&gt;nginx&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fu9if7m8bwx7ogk0tsoic.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%2Fu9if7m8bwx7ogk0tsoic.png" alt="Installing a web server" width="800" height="132"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next is to create a virtual host using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="nx"&gt;sudo&lt;/span&gt; &lt;span class="nx"&gt;vi&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;nginx&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;sites&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;available&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;copied_droplet_IP&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Paste the code below and save.&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%2Fz3ebtck6rzx990agk0k7.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%2Fz3ebtck6rzx990agk0k7.png" alt="Virtual host" width="800" height="473"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can now create a link using.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="nx"&gt;sudo&lt;/span&gt; &lt;span class="nx"&gt;ln&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;nginx&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;sites&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;available&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;copied_droplet_IP&lt;/span&gt;  &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;nginx&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;sites&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;enabled&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then reload &lt;code&gt;nginx&lt;/code&gt; using&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="nx"&gt;sudo&lt;/span&gt; &lt;span class="nx"&gt;systemctl&lt;/span&gt; &lt;span class="nx"&gt;reload&lt;/span&gt; &lt;span class="nx"&gt;nginx&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Testing deployment
&lt;/h2&gt;

&lt;p&gt;We can now go to the browser and paste the copied_droplet_IP. We should see our project management app on the page.&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%2Fvrcztp4uqczpbidoal70.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%2Fvrcztp4uqczpbidoal70.png" alt="Rendered app" width="800" height="431"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, we will see an error if we look at the console. This error is there because we have not set up the API server.&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%2F0u6fzur0gsmjvfa1ek41.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%2F0u6fzur0gsmjvfa1ek41.png" alt="API server error" width="800" height="431"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To take care of this, we must use &lt;code&gt;nginx&lt;/code&gt; to proxy &lt;code&gt;/API&lt;/code&gt; to the PostgREST instance running on our droplet, as described in this &lt;a href="https://postgrest.org/en/v10.2/admin.html?utm_source=hackmamba&amp;amp;utm_medium=blog&amp;amp;utm_id=HMBcommunity" rel="noopener noreferrer"&gt;PostgREST documentation.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can now edit our &lt;code&gt;nginx&lt;/code&gt; configuration using&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="nx"&gt;sudo&lt;/span&gt; &lt;span class="nx"&gt;vi&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;nginx&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;sites&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;available&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;Copied_IP&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, update the configuration with the command below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;     &lt;span class="nx"&gt;location&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;default_type&lt;/span&gt;  &lt;span class="nx"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="nx"&gt;proxy_hide_header&lt;/span&gt; &lt;span class="nx"&gt;Content&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;Location&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="nx"&gt;add_header&lt;/span&gt; &lt;span class="nx"&gt;Content&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;Location&lt;/span&gt;  &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;$upstream_http_content_location&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="nx"&gt;proxy_set_header&lt;/span&gt;  &lt;span class="nx"&gt;Connection&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="nx"&gt;proxy_http_version&lt;/span&gt; &lt;span class="mf"&gt;1.1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="nx"&gt;proxy_pass&lt;/span&gt; &lt;span class="na"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//localhost:3000/;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fnw4y5fay9thginq8qvh4.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%2Fnw4y5fay9thginq8qvh4.png" alt="Update nginx configuration" width="799" height="297"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then reload &lt;code&gt;nginx&lt;/code&gt; using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="nx"&gt;sudo&lt;/span&gt; &lt;span class="nx"&gt;systemctl&lt;/span&gt; &lt;span class="nx"&gt;reload&lt;/span&gt; &lt;span class="nx"&gt;nginx&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can now return to the browser and paste the copied Droplet IP. Now, we can see our application without any errors.&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%2Fydbi7spu56b6r474ildn.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%2Fydbi7spu56b6r474ildn.png" alt="Complete Page" width="800" height="675"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Congratulations! You successfully created a mini-project management application by seamlessly integrating PostgREST and DigitalOcean, backed by Neon serverless Postgres.&lt;/p&gt;

&lt;p&gt;Here are a few recommendations to take it further. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add a domain to the Droplet&lt;/li&gt;
&lt;li&gt;Configure HTTPS&lt;/li&gt;
&lt;li&gt;Add more features to the applications&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The possibilities are endless when it comes to Neon serverless Postgres.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;We covered a lot in this tutorial. Let’s recap! You accomplished the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Leveraged Neon serverless Postgres to establish a PostgREST API on DigitalOcean.&lt;/li&gt;
&lt;li&gt;Transformed a PostgreSQL database into a functional RESTful API using PostgREST.&lt;/li&gt;
&lt;li&gt;Created a mini-project management application as a practical illustration using VueJS.&lt;/li&gt;
&lt;li&gt;Demonstrated seamless integration between Neon serverless Postgres, PostgREST, and DigitalOcean.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  References
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://neon.tech/?ref=hm" rel="noopener noreferrer"&gt;Neon Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://postgrest.org/en/stable/?utm_id=HMBcommunity&amp;amp;utm_medium=blog&amp;amp;utm_source=hackmamba" rel="noopener noreferrer"&gt;PostgREST Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.digitalocean.com/products/droplets/how-to/create/?utm_source=hackmamba&amp;amp;utm_medium=blog&amp;amp;utm_id=HMBcommunity" rel="noopener noreferrer"&gt;How to Create a Droplet&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=iHtsALtD5-U" rel="noopener noreferrer"&gt;Building a Contacts List with PostgREST and Vue.js&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Understanding AWS Amplify Monitoring Metrics Definitions</title>
      <dc:creator>Femi Akinyemi</dc:creator>
      <pubDate>Thu, 08 Feb 2024 12:52:21 +0000</pubDate>
      <link>https://dev.to/aws-builders/understanding-aws-amplify-monitoring-metrics-definitions-43c2</link>
      <guid>https://dev.to/aws-builders/understanding-aws-amplify-monitoring-metrics-definitions-43c2</guid>
      <description>&lt;p&gt;One of the App settings provided by AWS Amplify is Monitoring, which allows us to monitor metrics like site traffic, configure alarms, and access logs for our Amplify applications in nearly real time. &lt;/p&gt;

&lt;p&gt;In this article, we will look at the definitions of CloudWatch metrics in the &lt;em&gt;AWS/AmplifyHosting&lt;/em&gt; namespace for monitoring our app traffic, errors, data transfer, and latency.&lt;/p&gt;

&lt;p&gt;When we decide to monitor our app hosted on AWS Amplify, we navigate to the app settings sidebar and click on the Monitoring tab, which takes us to the monitoring page, as shown in the image below.&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%2Foka9xv4bhdargzsf4e1p.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%2Foka9xv4bhdargzsf4e1p.png" alt="monitoring page" width="800" height="713"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, what do all these terms mean?&lt;/p&gt;

&lt;p&gt;According to the Monitoring and CloudWatch section of the AWS Amplify Hosting, Here is what they mean.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Requests:&lt;/strong&gt;  This is the total number of viewer requests Amplify Hosting receives for all HTTP methods and HTTP and HTTPS requests, which means it is how often people visit our website hosted on Amplify, including all types of requests like clicking links or loading pages with HTTP or HTTPS.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bytes downloaded:&lt;/strong&gt; The total amount of data transferred out of our app (downloaded) in bytes by viewers for GET, HEAD, and OPTIONS requests, which means it shows the total data sent from our app to users when they download something, like images or files, through actions like clicking links or accessing pages.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;BytesUploaded:&lt;/strong&gt; This is the total amount of data transferred into our app (uploaded) in bytes using POST and PUT requests. Therefore, it represents the complete data our app receives when users upload files or submit forms, typically through actions like posting comments or uploading images.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4XXErrors:&lt;/strong&gt; The number of requests that returned an error in the HTTP status code 400-499 range. This metric counts the requests that encountered errors on the user's end, like entering incorrect information or trying to access restricted content, resulting in an error response from the server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5XXErrors:&lt;/strong&gt; The number of requests that returned an error in the HTTP status code 500-599 range. This metric counts the requests that encountered errors on the user's end, like entering incorrect information or trying to access restricted content, resulting in an error response from the server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Latency:&lt;/strong&gt; This metric measures how quickly Amplify Hosting responds to a request, from when it receives it until it sends the first byte of data back to the network. It excludes the time the response travels to the viewer's device. &lt;br&gt;
Key statistics include the &lt;strong&gt;average&lt;/strong&gt;, &lt;strong&gt;maximum&lt;/strong&gt;, &lt;strong&gt;minimum&lt;/strong&gt;, and various percentiles (&lt;strong&gt;p10&lt;/strong&gt;, &lt;strong&gt;p50&lt;/strong&gt;, &lt;strong&gt;p90&lt;/strong&gt;, &lt;strong&gt;p95&lt;/strong&gt;, &lt;strong&gt;p100&lt;/strong&gt;), providing insights into response times across different scenarios.&lt;/p&gt;

&lt;p&gt;For more details about the metrics, we can access the CloudWatch metrics in the AWS Management Console &lt;a href="https://console.aws.amazon.com/cloudwatch/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cloudcomputing</category>
      <category>awsamplify</category>
      <category>javascript</category>
    </item>
    <item>
      <title>How to add Astro social share to your Astro application</title>
      <dc:creator>Femi Akinyemi</dc:creator>
      <pubDate>Mon, 08 Jan 2024 05:44:36 +0000</pubDate>
      <link>https://dev.to/femi_akinyemi/how-to-add-astro-social-share-to-your-astro-application-4bl1</link>
      <guid>https://dev.to/femi_akinyemi/how-to-add-astro-social-share-to-your-astro-application-4bl1</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://astro.build/?utm_source=hackmamba-community" rel="noopener noreferrer"&gt;Astr&lt;/a&gt;&lt;a href="https://astro.build/" rel="noopener noreferrer"&gt;o&lt;/a&gt; is a modern web framework that combines the best features of static site generators (SSGs) and server-side rendering (SSR) frameworks. It is designed to be fast, flexible, and easy to use, making it an excellent choice for building various websites, including blogs, portfolios, e-commerce sites, and more.&lt;/p&gt;

&lt;p&gt;Astro offers several benefits, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Speed:&lt;/strong&gt; Astro websites are typically very fast, thanks to server-side rendering and component islands.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;SEO:&lt;/strong&gt; Astro websites are also well-suited for SEO, as they are static and can be pre-rendered.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Flexibility:&lt;/strong&gt; Astro is a very flexible framework, and many websites can be built.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;User-friendliness:&lt;/strong&gt; Astro is beginner-friendly and offers a gentle learning curve, making it accessible even for those new to web development.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One of the benefits of using Astro is that it makes it easy to add social sharing buttons to your website. Social sharing is essential because social sharing is a great way to increase traffic to your website and promote your content.&lt;/p&gt;

&lt;p&gt;Social sharing is essential for web applications because it can help to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Boost website traffic&lt;/li&gt;
&lt;li&gt;Content promotion&lt;/li&gt;
&lt;li&gt;Establish brand presence&lt;/li&gt;
&lt;li&gt;Lead generation and sales&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This article explains how to add social sharing buttons to your Astro application.&lt;/p&gt;

&lt;p&gt;In this article, you will build an application that displays random jokes using the &lt;a href="https://icanhazdadjoke.com/?utm_source=hackmamba-community" rel="noopener noreferrer"&gt;random dad joke API&lt;/a&gt; with a social share button using &lt;a href="https://github.com/silent1mezzo/astro-social-share?utm_source=hackmamba-community" rel="noopener noreferrer"&gt;Astro social share&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The source code for the application is readily available here on &lt;a href="https://github.com/femakin/Astrol-Social-Share?utm_source=hackmamba-community" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;By the end of this article, you will have a better understanding of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What is Astro social share?&lt;/li&gt;
&lt;li&gt;How to install Astro social share&lt;/li&gt;
&lt;li&gt;How to use Astro social share
# Understanding Astro social share&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://github.com/silent1mezzo/astro-social-share?utm_source=hackmamba-community" rel="noopener noreferrer"&gt;Astro social share&lt;/a&gt; is your Astro site's social media share button. It's also one of the recently added Astro integrations.&lt;/p&gt;

&lt;p&gt;Astro social share comes with some good features, which are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No dependencies or external scrips&lt;/li&gt;
&lt;li&gt;Share buttons for:

&lt;ul&gt;
&lt;li&gt;Facebook&lt;/li&gt;
&lt;li&gt;Hacker News&lt;/li&gt;
&lt;li&gt;LinkedIn&lt;/li&gt;
&lt;li&gt;Reddit&lt;/li&gt;
&lt;li&gt;Twitter&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Icons included from &lt;a href="https://simpleicons.org/?utm_source=hackmamba-community" rel="noopener noreferrer"&gt;https://simpleicons.org/&lt;/a&gt;
# Prerequisites&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To fully grasp the concepts presented in this article, the following are required:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Basic understanding of JavaScript&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://nodejs.org/en/" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt; installed, version v18.14.1 or later.&lt;/li&gt;
&lt;li&gt;Code Editor - Preferably &lt;a href="https://code.visualstudio.com/" rel="noopener noreferrer"&gt;VS Code&lt;/a&gt; or another code editor.
# Bootstrapping Astro application&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To bootstrap your Astro application, you will use the &lt;code&gt;create astro&lt;/code&gt; setup wizard following the steps below:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install Astro by running the following command in your terminal:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;npm create astro@latest&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Confirm your choice by typing 'y' to install the &lt;code&gt;create-astro&lt;/code&gt; package.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When prompted to specify the location for your new project, enter the folder name where you'd like to create a new project directory. For example, you can type. /&lt;code&gt;Astro-Social-Share&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You'll be presented with a list of starter templates. Use the arrow keys (up and down) to navigate to the "Empty" template, and then press the &lt;code&gt;Return&lt;/code&gt; or &lt;code&gt;Enter&lt;/code&gt; key to select it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When asked if you want to install project dependencies, type &lt;code&gt;y&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If you are asked whether you plan on using TypeScript, type &lt;code&gt;n&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When prompted about initializing a new git repository, type &lt;code&gt;y&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, you can navigate to your &lt;code&gt;Astro-Social-Share&lt;/code&gt; directory to begin and preview your application by running the command below in your terminal:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd cd Astro-Social-Share

npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Click the localhost link within your terminal window to view a real-time preview of your brand-new Astro website!&lt;/p&gt;

&lt;p&gt;This is how the browser preview of the Astro 'Empty Project' starter website should appear:&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%2Fres.cloudinary.com%2Fpracticaldev%2Fimage%2Ffetch%2Fs--dEnO18w7--%2Fc_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_800%2Fhttps%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdhexffud1hawq3v6xwr4.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%2Fres.cloudinary.com%2Fpracticaldev%2Fimage%2Ffetch%2Fs--dEnO18w7--%2Fc_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_800%2Fhttps%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdhexffud1hawq3v6xwr4.png" alt="Astro Preview Page" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Setting up API page
&lt;/h1&gt;

&lt;p&gt;Now, you need to set up the Home Page. The home page will be the entry point for your application's home page. In the &lt;code&gt;src/pages/index.astro&lt;/code&gt;, paste the code below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
    &lt;span class="o"&gt;---&lt;/span&gt;
    &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;GET&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;../pages/api/fetchdata&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;TwitterShareButton&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SocialShare&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;astro-social-share&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;TwitterBUTTON&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;TwitterShareButton&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nc"&gt;GET&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;---&lt;/span&gt;

    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;html&lt;/span&gt; &lt;span class="nx"&gt;lang&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;en&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;h-screen flex flex-col items-center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-3xl font-bold mt-12 mb-12&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Share&lt;/span&gt; &lt;span class="nx"&gt;Your&lt;/span&gt; &lt;span class="nx"&gt;Daily&lt;/span&gt; &lt;span class="nx"&gt;Joke&lt;/span&gt; &lt;span class="nx"&gt;on&lt;/span&gt; &lt;span class="nx"&gt;X&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;
            &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;joke-btn&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
            &lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bg-blue-500 hover-bg-blue-700 text-white font-bold py-2 px-4 rounded&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nx"&gt;Click&lt;/span&gt; &lt;span class="nx"&gt;on&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;X&lt;/span&gt; &lt;span class="nx"&gt;icon&lt;/span&gt; &lt;span class="nx"&gt;below&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;share&lt;/span&gt; &lt;span class="nx"&gt;your&lt;/span&gt; &lt;span class="nx"&gt;daily&lt;/span&gt; &lt;span class="nx"&gt;joke&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mt-12&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;joke-container&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;joke&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;SocialShare&lt;/span&gt;
            &lt;span class="nx"&gt;buttons&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;TwitterBUTTON&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;joke&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="nx"&gt;via&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;akinyemi_t&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
            &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;joke&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/body&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/html&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is the explanation of the code provided above:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The first line imports the GET function from a file at &lt;code&gt;../pages/api/fetchdata&lt;/code&gt;. It suggests that you are making a &lt;code&gt;GET&lt;/code&gt; request to fetch some data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Next, you import components related to social sharing using Astro. Specifically, you import the &lt;code&gt;TwitterShareButton&lt;/code&gt; and &lt;code&gt;SocialShare&lt;/code&gt; components from the &lt;code&gt;astro-social-share&lt;/code&gt; library.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You define &lt;code&gt;TwitterBUTTON&lt;/code&gt; as an array containing the &lt;code&gt;TwitterShareButton&lt;/code&gt;. This variable plays a role later when configuring social sharing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The code then awaits the result of the &lt;code&gt;GET&lt;/code&gt; request, assigns it to the &lt;code&gt;response&lt;/code&gt; variable, and parses the &lt;code&gt;JSON&lt;/code&gt; content from the response into the data variable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The HTML section starts with the opening &lt;code&gt;&amp;lt;html&amp;gt;&lt;/code&gt; tag and defines the web page's structure.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Inside the &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; tag, the content of the web page looks as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; element with the class &lt;code&gt;h-screen flex flex-col items-center&lt;/code&gt; is used to center the content vertically in the viewport.&lt;/li&gt;
&lt;li&gt;An &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; element with the text &lt;code&gt;Share Your Daily Joke on X&lt;/code&gt; is displayed at the top of the page.&lt;/li&gt;
&lt;li&gt;A &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt; element with the ID &lt;code&gt;joke-btn&lt;/code&gt; displays a message encouraging the user to click an &lt;code&gt;X&lt;/code&gt; icon below to share a daily joke.&lt;/li&gt;
&lt;li&gt;Another &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; element with the ID &lt;code&gt;joke-container&lt;/code&gt; displays the content of the &lt;code&gt;data.joke&lt;/code&gt; property, which contains the daily joke fetched from the &lt;code&gt;API.&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;&amp;lt;SocialShare&amp;gt;&lt;/code&gt; component enables sharing on social media. Configured with the buttons prop set to &lt;code&gt;TwitterBUTTON&lt;/code&gt; (likely to display a Twitter share button), the description assigned to the &lt;code&gt;data.joke&lt;/code&gt; set to &lt;code&gt;akinyemi_t&lt;/code&gt; (the Twitter username), and the joke's title. Text.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Testing and debugging
&lt;/h1&gt;

&lt;p&gt;Follow the steps below to test your application:&lt;/p&gt;

&lt;p&gt;Navigate into your directory and run&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Your application is now running at &lt;code&gt;localhost:4321&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;To view your homepage, visit &lt;code&gt;localhost:4321&lt;/code&gt; in your browser. You should see the homepage.&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%2Fres.cloudinary.com%2Fpracticaldev%2Fimage%2Ffetch%2Fs--rYnSU3JD--%2Fc_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_800%2Fhttps%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frimfobwd3n6q00fn0h66.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%2Fres.cloudinary.com%2Fpracticaldev%2Fimage%2Ffetch%2Fs--rYnSU3JD--%2Fc_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_800%2Fhttps%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frimfobwd3n6q00fn0h66.png" alt="Final Demo Page" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, you can share your joke on social media by clicking the X icon.&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%2Fres.cloudinary.com%2Fpracticaldev%2Fimage%2Ffetch%2Fs--baS2VNRy--%2Fc_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_800%2Fhttps%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpvknakxu707ac8xemgj3.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%2Fres.cloudinary.com%2Fpracticaldev%2Fimage%2Ffetch%2Fs--baS2VNRy--%2Fc_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_800%2Fhttps%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpvknakxu707ac8xemgj3.png" alt=" " width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  What's next?
&lt;/h1&gt;

&lt;p&gt;There are so many other things you can do with Astro social share. You can integrate other social buttons, like&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Facebook&lt;/li&gt;
&lt;li&gt;Hacker News&lt;/li&gt;
&lt;li&gt;LinkedIn&lt;/li&gt;
&lt;li&gt;Reddit&lt;/li&gt;
&lt;li&gt;Twitter&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also, you can make the application more interactive by adding more features like changing the jokes.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Astro is a fast and flexible web framework suitable for various website types. Adding social sharing buttons to your Astro application enhances traffic, content promotion, brand presence, and lead generation.&lt;/p&gt;

&lt;p&gt;This article has shown how to integrate social sharing buttons using the Astro social share component, using a random joke application as an example.&lt;/p&gt;

&lt;p&gt;The provided GitHub source code serves as a practical reference.&lt;/p&gt;

&lt;p&gt;By following the article, you've gained the ability to empower your web applications with Astro social share, making your content more shareable and engaging.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>astro</category>
      <category>javascript</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to Prevent Unnecessary React Component Re-Rendering</title>
      <dc:creator>Femi Akinyemi</dc:creator>
      <pubDate>Sat, 08 Jul 2023 05:48:48 +0000</pubDate>
      <link>https://dev.to/femi_akinyemi/how-to-prevent-unnecessary-react-component-re-rendering-3c08</link>
      <guid>https://dev.to/femi_akinyemi/how-to-prevent-unnecessary-react-component-re-rendering-3c08</guid>
      <description>&lt;p&gt;Understanding how &lt;a href="https://react.dev/" rel="noopener noreferrer"&gt;React&lt;/a&gt; renders components is essential for building efficient and performant applications. When a component’s state or props change, React automatically updates the User Interface(UI) to reflect those changes. As a result, React calls the component's render method again to generate the updated UI representation.&lt;/p&gt;

&lt;p&gt;In this article, we will explore three React Hooks and how they prevent unnecessary renderings in React&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://react.dev/reference/react/useMemo" rel="noopener noreferrer"&gt;useMemo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://react.dev/reference/react/useCallback" rel="noopener noreferrer"&gt;useCallback&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://react.dev/reference/react/useRef" rel="noopener noreferrer"&gt;useRef&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These tools allow us to optimize our code by avoiding unnecessary re-renders, improving performance, and storing values efficiently.&lt;/p&gt;

&lt;p&gt;By the end of this article, we'll better understand how to make our React applications faster and more responsive using these handy React hooks.&lt;/p&gt;

&lt;h1&gt;
  
  
  Using React's useMemo
&lt;/h1&gt;

&lt;p&gt;In React, &lt;code&gt;useMemo&lt;/code&gt; can prevent unnecessary re-renderings and optimize performance.&lt;/p&gt;

&lt;p&gt;Let's explore how the &lt;code&gt;useMemo&lt;/code&gt; hook can prevent unnecessary re-renders in our React components.&lt;/p&gt;

&lt;p&gt;By memorizing the result of a function and tracking its dependencies, &lt;code&gt;useMemo&lt;/code&gt; ensures that the process is recomputed only when necessary.&lt;/p&gt;

&lt;p&gt;Consider the following example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useMemo&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="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Page&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&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;items&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="nf"&gt;generateItems&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;300&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;selectedItem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useMemo&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;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;item&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;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;]);&lt;/span&gt;

      &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;generateItems&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&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;items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
        &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;isSelected&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tutorial&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Selected&lt;/span&gt; &lt;span class="nx"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;selectedItem&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Increment&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;The code above is a React component called &lt;code&gt;Page&lt;/code&gt; that uses &lt;code&gt;useMemo&lt;/code&gt; to optimize the &lt;code&gt;selectedItem&lt;/code&gt; calculation.&lt;/p&gt;

&lt;p&gt;Here's the explanation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The component maintains a state variable &lt;code&gt;count&lt;/code&gt; using the &lt;code&gt;useState&lt;/code&gt; hook.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;code&gt;items&lt;/code&gt; state is initialized using the &lt;code&gt;useState&lt;/code&gt; hook with the result of the &lt;code&gt;generateItems&lt;/code&gt;function.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;code&gt;selectedItem&lt;/code&gt; is calculated using &lt;code&gt;useMemo,&lt;/code&gt; which memorizes the result of the &lt;code&gt;items.find&lt;/code&gt; operation. It only re-calculates when either &lt;code&gt;count&lt;/code&gt; or &lt;code&gt;items&lt;/code&gt; change.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;code&gt;generateItems&lt;/code&gt; function generates an array of items based on the given count.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The component renders the current &lt;code&gt;**count**&lt;/code&gt; value, the &lt;code&gt;selectedItem id,&lt;/code&gt; and a button to increment the &lt;code&gt;count&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using &lt;code&gt;useMemo&lt;/code&gt; optimizes performance by memoizing the result of the &lt;code&gt;items.find&lt;/code&gt; operation. It ensures that the calculation of &lt;code&gt;selectedItem&lt;/code&gt; is only performed when the dependencies (&lt;code&gt;count&lt;/code&gt; or &lt;code&gt;items&lt;/code&gt;) change, preventing unnecessary re-calculations on subsequent renders.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Memoization should be employed selectively for computationally intensive operations, as it introduces additional overhead to the rendering process.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Using React's useCallback
&lt;/h1&gt;

&lt;p&gt;The &lt;code&gt;useCallback&lt;/code&gt; hook in React allows for the memoization of functions, preventing them from being recreated during each component render. By utilizing &lt;code&gt;useCallback&lt;/code&gt;. a part is created only once and reused in subsequent renders as long as its dependencies remain unchanged.&lt;/p&gt;

&lt;p&gt;Consider the following example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&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="nx"&gt;useCallback&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;memo&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="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;allColors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;red&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="s1"&gt;green&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="s1"&gt;blue&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="s1"&gt;yellow&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="s1"&gt;orange&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;shuffle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;shuffledArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
      &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;shuffledArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;j&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;shuffledArray&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;shuffledArray&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;shuffledArray&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;shuffledArray&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]];&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;shuffledArray&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;Filter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;memo&lt;/span&gt;&lt;span class="p"&gt;(({&lt;/span&gt; &lt;span class="nx"&gt;onChange&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="s1"&gt;Filter rendered!&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;
          &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
          &lt;span class="nx"&gt;placeholder&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Filter colors...&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
          &lt;span class="nx"&gt;onChange&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="nf"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
        &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Page&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;colors&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setColors&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="nx"&gt;allColors&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;colors&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleFilter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useCallback&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;filteredColors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;allColors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;color&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;color&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nf"&gt;setColors&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;filteredColors&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;colors&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;


      &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tutorial&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;align-center mb-2 flex&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setColors&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;shuffle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;allColors&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;Shuffle&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Filter&lt;/span&gt; &lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleFilter&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ul&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;colors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;li&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;color&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;color&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/li&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="p"&gt;))}&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/ul&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;The code above demonstrates a simple color filtering and shuffling functionality in a React component. Let's go through it step by step:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The initial array of colors is defined as &lt;code&gt;allColors&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;code&gt;shuffle&lt;/code&gt; function takes an array and shuffles its elements randomly. It uses the Fisher-Yates algorithm to achieve shuffling.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;code&gt;Filter&lt;/code&gt; component is a memoized functional component that renders an input element. It receives an onChange prop and triggers the callback function when the input value changes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The Page component is the main component that renders the color filtering and shuffling functionality.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The state variable colors are initialized using the &lt;code&gt;useState&lt;/code&gt; hook, with the initial value set to &lt;code&gt;allColors&lt;/code&gt;. It represents the filtered list of colors.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;code&gt;handleFilter&lt;/code&gt; function is created using the &lt;code&gt;useCallback&lt;/code&gt; hook. It takes a &lt;code&gt;text&lt;/code&gt; parameter and filters the &lt;code&gt;allColors&lt;/code&gt; array based on the provided &lt;code&gt;text.&lt;/code&gt; The filtered colors are then set using the &lt;code&gt;setColors&lt;/code&gt; function from the &lt;code&gt;useState&lt;/code&gt; hook. The dependency array &lt;code&gt;[colors]&lt;/code&gt; ensures that the &lt;code&gt;handleFilter&lt;/code&gt; function is only recreated if the &lt;code&gt;colors&lt;/code&gt; state changes, optimizing performance by preventing unnecessary re-renders.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Inside the &lt;code&gt;Page&lt;/code&gt; component is a button for shuffling the colors. When the button clicks, it calls the &lt;code&gt;setColors&lt;/code&gt; function with the shuffled array of &lt;code&gt;allColors&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;code&gt;Filter&lt;/code&gt; component is rendered with the &lt;code&gt;onChange&lt;/code&gt; prop set to the &lt;code&gt;handleFilter&lt;/code&gt; function.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Finally, the &lt;code&gt;colors&lt;/code&gt; array is mapped to render the list of color items as &lt;code&gt;&amp;lt;li&amp;gt;&lt;/code&gt; elements.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code&gt;useCallback&lt;/code&gt; hook is used to memoize the &lt;code&gt;handleFilter&lt;/code&gt; function, which means the function is only created once and reused on subsequent renders if the dependencies (in this case, the &lt;code&gt;colors&lt;/code&gt; state) remain the same.&lt;/p&gt;

&lt;p&gt;This optimization prevents unnecessary re-renders of child components that receive the &lt;code&gt;handleFilter&lt;/code&gt; function as a prop, such as the &lt;code&gt;Filter&lt;/code&gt; component.&lt;br&gt;
It ensures that the &lt;code&gt;Filter&lt;/code&gt; component is not re-rendered if the &lt;code&gt;colors&lt;/code&gt; state hasn't changed, improving performance.&lt;/p&gt;
&lt;h1&gt;
  
  
  Using React's useRef
&lt;/h1&gt;

&lt;p&gt;Another approach to enhance performance in React applications and avoid unnecessary re-renders is using the &lt;code&gt;useRef&lt;/code&gt; hook. Using &lt;code&gt;useRef&lt;/code&gt;, we can store a mutable value that persists across renders, effectively preventing unnecessary re-renders.&lt;/p&gt;

&lt;p&gt;This technique allows us to maintain a reference to a value without triggering component updates when that value changes. By leveraging the mutability of the reference, we can optimize performance in specific scenarios.&lt;/p&gt;

&lt;p&gt;Consider the following example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useRef&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="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="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;setName&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="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;inputRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRef&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;function&lt;/span&gt; &lt;span class="nf"&gt;handleClick&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;inputRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;focus&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;
            &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
            &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="nx"&gt;onChange&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="nf"&gt;setName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
            &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;inputRef&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleClick&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;Focus&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;The example above has a simple input field and a button. The &lt;code&gt;useRef&lt;/code&gt; hook creates a ref called &lt;code&gt;inputRef.&lt;/code&gt; As soon as the button is clicked, the &lt;code&gt;handleClick&lt;/code&gt; function is called, which focuses on the input element by accessing the &lt;code&gt;current&lt;/code&gt; property of the &lt;code&gt;inputRef&lt;/code&gt; ref object. As such, it prevents unnecessary rerendering of the component when the input value changes.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;To ensure optimal use of `&lt;/strong&gt;useRef,&lt;strong&gt;` reserve it solely for mutable values that do not impact the component's rendering. If a mutable value influences the component's rendering, it should be stored within its state instead.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Throughout this tutorial, we explored the concept of React re-rendering and its potential impact on the performance of our applications. We delved into the optimization techniques that can help mitigate unnecessary re-renders. React offers a variety of hooks that enable us to enhance the performance of our applications. We can effectively store values and functions between renders by leveraging these hooks, significantly boosting React application performance.&lt;/p&gt;

&lt;h1&gt;
  
  
  References
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://blog.openreplay.com/how-to-stop-react-components-from-rerendering/" rel="noopener noreferrer"&gt;How To Stop React Components From Re-Rendering&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.smashingmagazine.com/2020/07/methods-performance-react-apps/" rel="noopener noreferrer"&gt;Methods Of Improving And Optimizing Performance In React Apps&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>performance</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Build A Reusable Carousel With React And Splide.js</title>
      <dc:creator>Femi Akinyemi</dc:creator>
      <pubDate>Tue, 13 Jun 2023 22:23:42 +0000</pubDate>
      <link>https://dev.to/femi_akinyemi/build-a-reusable-carousel-with-react-and-splidejs-422h</link>
      <guid>https://dev.to/femi_akinyemi/build-a-reusable-carousel-with-react-and-splidejs-422h</guid>
      <description>&lt;p&gt;In today's rapidly evolving web development landscape, the importance of creating reusable components cannot be overstated. These components play a vital role in enhancing efficiency and ensuring maintainability. Carousels are a popular choice among the widely utilized components in web design. A carousel enables users to navigate seamlessly through a collection of images or items in a sliding manner.&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%2Fa74syh898aih10hxdtah.gif" 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%2Fa74syh898aih10hxdtah.gif" alt="Thumbnail Carousel" width="560" height="463"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this article, you will build a reusable carousel component using &lt;a href="https://react.dev/" rel="noopener noreferrer"&gt;React&lt;/a&gt; and &lt;a href="https://splidejs.com/" rel="noopener noreferrer"&gt;Splide.Js&lt;/a&gt; — a lightweight and versatile slider library. &lt;/p&gt;

&lt;p&gt;By following a systematic approach, you will cover the installation of necessary dependencies and the implementation of fundamental functionalities. Upon concluding this article, you will comprehensively understand crafting a fully functional and reusable carousel component with React and Splide.js. &lt;/p&gt;

&lt;p&gt;This accomplishment will equip you to integrate the carousel into your future web projects effortlessly.&lt;/p&gt;

&lt;h1&gt;
  
  
  Why Splide?
&lt;/h1&gt;

&lt;p&gt;Splide.js is a lightweight, flexible, and accessible slider and carousel library for creating web-based sliders and carousels. &lt;/p&gt;

&lt;p&gt;It’s written in TypeScript and supports various features, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Autoplay with a progress bar and a play-pause toggle button&lt;/li&gt;
&lt;li&gt;Multiple slides&lt;/li&gt;
&lt;li&gt;Slide or fade transition by CSS&lt;/li&gt;
&lt;li&gt;Flexible and extensible&lt;/li&gt;
&lt;li&gt;Protected by 400+ test cases&lt;/li&gt;
&lt;li&gt;Lightweight, 29kB (12kB gzipped)&lt;/li&gt;
&lt;li&gt;No dependencies&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And many others.&lt;/p&gt;

&lt;h1&gt;
  
  
  Splide installation
&lt;/h1&gt;

&lt;p&gt;To install Splide into your project, you can choose one of the four options listed below:&lt;/p&gt;

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

&lt;p&gt;It is recommended to install Splide using NPM. To install the latest version, use the following command to do so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;npm&lt;/span&gt; &lt;span class="nx"&gt;install&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;splidejs&lt;/span&gt;&lt;span class="sr"&gt;/splid&lt;/span&gt;&lt;span class="err"&gt;e
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Hosting Files&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can download the Splide package from the following link:&lt;br&gt;
&lt;a href="https://github.com/Splidejs/splide/releases/latest/" rel="noopener noreferrer"&gt;Download&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, Go to the &lt;code&gt;dist/js&lt;/code&gt; directory, and import the &lt;code&gt;splide.min.js&lt;/code&gt; file by the &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;path-to-the-file/splide.min.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;You can also include this library from CDN:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.jsdelivr.com/package/npm/@splidejs/splide?path=dist" rel="noopener noreferrer"&gt;jsDelivr&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is recommended to use &lt;strong&gt;a specific version number&lt;/strong&gt; instead of the "latest" keyword for production to avoid unexpected breakage from the further update.&lt;/p&gt;

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

&lt;p&gt;Integration packages are available for React, Vue and Svelte.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://splidejs.com/integration/react-splide/" rel="noopener noreferrer"&gt;React Splide&lt;/a&gt;&lt;br&gt;
&lt;a href="https://splidejs.com/integration/vue-splide/" rel="noopener noreferrer"&gt;Vue Splide&lt;/a&gt;&lt;br&gt;
&lt;a href="https://splidejs.com/integration/svelte-splide/" rel="noopener noreferrer"&gt;Svelte Splide&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Integrating Splide with React
&lt;/h1&gt;

&lt;p&gt;To Integrate Splide with React, you will use the recommended installation method, NPM, to install React Splide, a React component for a Splide slider/carousel.&lt;/p&gt;
&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;p&gt;First, you must create a React.js starter project by navigating to your desired directory and running the command below in your terminal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;npx&lt;/span&gt; &lt;span class="nx"&gt;create&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;react&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="nx"&gt;splidereacttutorial&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;cd&lt;/span&gt; &lt;span class="nx"&gt;splidereacttutorial&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The command creates a React.js project called &lt;code&gt;splidereacttutorial&lt;/code&gt; and navigates into the project directory.&lt;/p&gt;

&lt;p&gt;Next, you need to Install Splide by running the following command in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;$&lt;/span&gt; &lt;span class="nx"&gt;npm&lt;/span&gt; &lt;span class="nx"&gt;install&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;splidejs&lt;/span&gt;&lt;span class="sr"&gt;/splid&lt;/span&gt;&lt;span class="err"&gt;e
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Usage
&lt;/h1&gt;

&lt;p&gt;In the &lt;code&gt;src&lt;/code&gt; directory, create a folder with the name &lt;code&gt;components&lt;/code&gt;. The directory will contain all the reusable components for the carousel.&lt;/p&gt;

&lt;h2&gt;
  
  
  Carousel Component
&lt;/h2&gt;

&lt;p&gt;In the &lt;code&gt;src&lt;/code&gt; directory, create the file &lt;code&gt;src/components/Carousel&lt;/code&gt; and add the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Splide&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SplideSlide&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;@splidejs/react-splide&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@splidejs/react-splide/css&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Carousel&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;
      &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;
        &lt;span class="na"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;flex&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;justifyContent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;alignItems&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;}}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Splide&lt;/span&gt;
        &lt;span class="nx"&gt;aria&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;My Favorite Images&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;
          &lt;span class="na"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;flex&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;justifyContent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;alignItems&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;center&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;options&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;
          &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;50%&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;}}&lt;/span&gt;
      &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;SplideSlide&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;img&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;img_one&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;img_alt&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/SplideSlide&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;SplideSlide&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;img&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;img_two&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;img_alt&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/SplideSlide&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Splide&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

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

&lt;/div&gt;



&lt;p&gt;The code above implements a React functional component called Carousel. It uses the &lt;code&gt;Splide&lt;/code&gt; and &lt;code&gt;SplideSlide&lt;/code&gt; components from the &lt;code&gt;@splidejs/react-splide&lt;/code&gt; library to render a carousel with two slides that contain images. The component accepts &lt;strong&gt;image URLs&lt;/strong&gt;, &lt;strong&gt;alternate text&lt;/strong&gt;, and &lt;strong&gt;styling&lt;/strong&gt; as props and displays the images within the carousel.&lt;/p&gt;

&lt;p&gt;Also, In the &lt;code&gt;src/App.css&lt;/code&gt; file, replace the code with the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="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="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;justify&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;align&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code above uses CSS to style the &lt;code&gt;.App&lt;/code&gt; class, making it a flex container that horizontally and vertically centers its child elements.&lt;/p&gt;

&lt;p&gt;Now, n the &lt;code&gt;src/App.js&lt;/code&gt; replace the code with the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./App.css&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Carousel&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./components/Carousel&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="na"&gt;img_one&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://images.creativefabrica.com/products/previews/2023/05/11/zZEZKFvQo/2Pdr8is8AS0vymhPaFPB1WOZ7DF-desktop.jpg&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;img_two&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://iso.500px.com/wp-content/uploads/2016/03/stock-photo-142984111-1500x1000.jpg&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;img_alt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;image_alt&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;100%&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;400px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;objectFit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cover&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;


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

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;
        &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;
          &lt;span class="na"&gt;textAlign&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;}}&lt;/span&gt;
      &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nx"&gt;Basic&lt;/span&gt; &lt;span class="nx"&gt;Carousel&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;App&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Carousel&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

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

&lt;/div&gt;



&lt;p&gt;The code above imports a CSS file named &lt;code&gt;App.css&lt;/code&gt; and a component called &lt;code&gt;Carousel&lt;/code&gt; from &lt;code&gt;./components/Carousel.&lt;/code&gt;&lt;br&gt;
Inside the &lt;code&gt;App&lt;/code&gt; function component, an object named &lt;code&gt;props&lt;/code&gt; is defined, which contains properties for two images (&lt;code&gt;img_one&lt;/code&gt; and &lt;code&gt;img_two&lt;/code&gt;), an alternate text for the images (&lt;code&gt;img_alt&lt;/code&gt;), and styling information.&lt;/p&gt;

&lt;p&gt;The component returns JSX elements, including a &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; heading with the text &lt;code&gt;Basic Carousel&lt;/code&gt; centered using inline styles.&lt;br&gt;
Within an &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; element with the class &lt;code&gt;App,&lt;/code&gt; the &lt;code&gt;Carousel&lt;/code&gt; component is rendered with the &lt;code&gt;props&lt;/code&gt; object passed as a prop.&lt;/p&gt;
&lt;h2&gt;
  
  
  Testing the Carousel component
&lt;/h2&gt;

&lt;p&gt;To test the Carousel component, Navigate into your &lt;code&gt;splidereacttutorial&lt;/code&gt; directory and run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;npm&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your Carousel component is now running at &lt;code&gt;localhost:3000&lt;/code&gt;&lt;br&gt;
To view the Carousel, visit &lt;code&gt;localhost:3000&lt;/code&gt; in your browser. You should see the component rendered.&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%2Fbqa3dlk7gkwqwk746g9i.gif" 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%2Fbqa3dlk7gkwqwk746g9i.gif" alt="Basic Carousel Component" width="600" height="443"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Creating Auto-scroll Carousel
&lt;/h1&gt;

&lt;p&gt;To create an auto-scroll carousel, you will use The &lt;a href="https://github.com/Splidejs/splide-extension-auto-scroll" rel="noopener noreferrer"&gt;Auto Scroll extension&lt;/a&gt; that continuously scrolls the carousel, which goes well with "Drag Free" mode.&lt;/p&gt;

&lt;p&gt;To Install The Auto Scroll extension, run the command below in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;npm&lt;/span&gt; &lt;span class="nx"&gt;install&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;splidejs&lt;/span&gt;&lt;span class="sr"&gt;/splide-extension-auto-scrol&lt;/span&gt;&lt;span class="err"&gt;l
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, In the &lt;code&gt;src/components/Carousel&lt;/code&gt; file,  Replace the code with the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Splide&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SplideSlide&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;@splidejs/react-splide&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;AutoScroll&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;@splidejs/splide-extension-auto-scroll&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@splidejs/react-splide/css&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Carousel&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Splide&lt;/span&gt;

        &lt;span class="c1"&gt;// ...&lt;/span&gt;

        &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;
          &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;100%&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;rewind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;autoplay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;true&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;perPage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;perMove&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2rem&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;15rem&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;loop&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;rewindSpeed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;3000&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;arrows&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;true&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;pagination&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;false&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;extensions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;AutoScroll&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="na"&gt;autoScroll&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;speed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;pauseOnHover&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;pauseOnFocus&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="na"&gt;breakpoints&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="na"&gt;perPage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;}}&lt;/span&gt;

        &lt;span class="c1"&gt;// ...&lt;/span&gt;

      &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* ... */&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Splide&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

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

&lt;/div&gt;



&lt;p&gt;The code above sets various options for the Splide carousel component. It configures properties such as &lt;strong&gt;width&lt;/strong&gt;, &lt;strong&gt;rewind behavior&lt;/strong&gt;, &lt;strong&gt;autoplay&lt;/strong&gt;, &lt;strong&gt;slide count&lt;/strong&gt;, &lt;strong&gt;spacing&lt;/strong&gt;, &lt;strong&gt;height&lt;/strong&gt;, &lt;strong&gt;looping&lt;/strong&gt;, &lt;strong&gt;rewind speed&lt;/strong&gt;, &lt;strong&gt;navigation arrows&lt;/strong&gt;, &lt;strong&gt;pagination&lt;/strong&gt;, &lt;strong&gt;extensions&lt;/strong&gt;, &lt;strong&gt;auto-scrolling behavior&lt;/strong&gt;, and &lt;strong&gt;responsive breakpoints&lt;/strong&gt;. These options define the carousel's appearance, behavior, and responsiveness.&lt;/p&gt;

&lt;p&gt;To test the Auto Scroll extension, visit &lt;code&gt;localhost:3000&lt;/code&gt; in your browser. You should see the component rendered below the Basic Carousel. &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%2Fzpse3g3kt024p9i67wwi.gif" 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%2Fzpse3g3kt024p9i67wwi.gif" alt="Auto Scroll" width="600" height="166"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Creating a Thumbnail Carousel
&lt;/h1&gt;

&lt;p&gt;To create a Thumbnail Carousel, In the &lt;code&gt;src&lt;/code&gt; directory, create a file with the name &lt;code&gt;Thumbnail.js&lt;/code&gt; and paste the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../App.css&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Splide&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SplideSlide&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;@splidejs/react-splide&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@splidejs/react-splide/css&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;p1&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;./firstimage.jpeg&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;p2&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;./secondimage.jpeg&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;p3&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./thirdimage.jpeg&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;p4&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./fourthimage.jpeg&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useRef&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;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Thumbnail&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;thumbsImages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;p1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;p2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;p3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;p4&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;mainOptions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;loop&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;perPage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;perMove&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1rem&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;pagination&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;27.8125rem&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="nx"&gt;style&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;100%&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;400px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;objectFit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cover&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="nx"&gt;generalStyle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0 auto&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;50%&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;btn_img&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;70px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;70px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;overflow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hidden&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;listStyle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0 0.2rem&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pointer&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;thumbnailsstyle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;flex&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;justifyContent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;alignItems&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;listStyle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;none&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;mainRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRef&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;handleThumbs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mainRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;mainRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;go&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;App_&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;generalStyle&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;  &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Splide&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;mainOptions&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;mainRef&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{}}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;SplideSlide&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;img&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;p1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;product imag 1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/SplideSlide&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;SplideSlide&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;img&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;p2&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;product imag 2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/SplideSlide&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;SplideSlide&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;img&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;p3&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;product imag 2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/SplideSlide&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;SplideSlide&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;img&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;p4&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;product imag 2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/SplideSlide&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Splide&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ul&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;thumbnailsstyle&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;thumbsImages&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;thumbnail&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;li&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;thumbnail&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;handleThumbs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;img&lt;/span&gt;
                    &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;thumbnail&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                    &lt;span class="nx"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;product thumbnail&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                    &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;btn_img&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                  &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/li&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="p"&gt;))}&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/ul&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;The code above is a React component that displays a main image carousel/slider and thumbnail images. It uses the &lt;code&gt;Splide&lt;/code&gt; component from &lt;code&gt;@splidejs/react-splide&lt;/code&gt; to create the carousel and handles thumbnail clicks to update the main carousel. The component defines image paths, carousel options, and styling objects. It renders the main carousel and thumbnail buttons using the &lt;code&gt;map&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;Now, In the &lt;code&gt;src/App.js&lt;/code&gt; file,  Replace the code with the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./App.css&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Thumbnail&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./components/Thumbnail&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;
        &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;
          &lt;span class="na"&gt;textAlign&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;}}&lt;/span&gt;
      &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nx"&gt;Thumbnail&lt;/span&gt; &lt;span class="nx"&gt;Carousel&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;App&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Thumbnail&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

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

&lt;/div&gt;



&lt;p&gt;This code above is a component that serves as the application's main entry point. It imports the &lt;code&gt;Thumbnail&lt;/code&gt; component and the &lt;code&gt;App.css&lt;/code&gt; file for styling.&lt;/p&gt;

&lt;p&gt;Inside the &lt;code&gt;App&lt;/code&gt; component, it renders a heading with the text &lt;strong&gt;Thumbnail Carousel&lt;/strong&gt; centered using inline styling. It also renders a &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; with the class name &lt;strong&gt;App&lt;/strong&gt; and includes the &lt;code&gt;Thumbnail&lt;/code&gt; component.&lt;/p&gt;

&lt;p&gt;To test the Thumbnail Carousel, visit &lt;code&gt;localhost:3000&lt;/code&gt; in your browser. &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%2Fa74syh898aih10hxdtah.gif" 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%2Fa74syh898aih10hxdtah.gif" alt="Thumbnail Carousel" width="560" height="463"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Creating a Video Carousel
&lt;/h1&gt;

&lt;p&gt;To create the Video Carousel, you will use The &lt;a href="https://github.com/Splidejs/splide-extension-video" rel="noopener noreferrer"&gt;Video extension&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To Install The Video Carousel extension, run the command below in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;npm&lt;/span&gt; &lt;span class="nx"&gt;install&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;splidejs&lt;/span&gt;&lt;span class="sr"&gt;/splide-extension-vide&lt;/span&gt;&lt;span class="err"&gt;o
&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, In the &lt;code&gt;src&lt;/code&gt; directory, create a file with the name &lt;code&gt;VideoCarousel.js&lt;/code&gt; and paste the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useRef&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Splide&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SplideSlide&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;@splidejs/react-splide&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Video&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;@splidejs/splide-extension-video&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@splidejs/splide-extension-video/dist/css/splide-extension-video.min.css&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;VideoCarousel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;rewind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;autoPlay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;perPage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;videos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;iRmx-btWrFk&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;liJVSwOiiwg&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;hAAZx5fHMZY&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;slideImageStyle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;maxWidth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;100%&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;auto&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="nx"&gt;mainRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRef&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Splide&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;extensions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;Video&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;mainRef&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;videos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;SplideSlide&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;splide&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;youtube&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;iframe&lt;/span&gt;
              &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;slideImageStyle&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
              &lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;900&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
              &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`YouTube Sample &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
              &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`https://www.youtube.com/embed/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/iframe&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/SplideSlide&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="p"&gt;))}&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Splide&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

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

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

&lt;/div&gt;



&lt;p&gt;The code above uses the Splide library and the Splide Video extension in React to set up a video carousel. It defines the &lt;code&gt;VideoCarousel&lt;/code&gt; component, configures the carousel options, and specifies an array of video IDs. The component renders a &lt;code&gt;Splide&lt;/code&gt; component with &lt;code&gt;SplideSlide&lt;/code&gt; components inside, each containing an embedded &lt;code&gt;iframe&lt;/code&gt; with a YouTube video. The &lt;code&gt;ref&lt;/code&gt; attribute is used to access the Splide instance. It creates a functional video carousel component using Splide and Splide Video extensions.&lt;/p&gt;

&lt;p&gt;Now, In the &lt;code&gt;src/App.js&lt;/code&gt; file, Replace the code with the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./App.css&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;VideoCarousel&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./components/VideoCarousel&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;
        &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;
          &lt;span class="na"&gt;textAlign&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;}}&lt;/span&gt;
      &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nx"&gt;Video&lt;/span&gt; &lt;span class="nx"&gt;Carousel&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;VideoCarousel&lt;/span&gt;&lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;This code above is a component that serves as the application's main entry point. It imports the &lt;code&gt;VideoCarousel&lt;/code&gt; component and the &lt;code&gt;App.css&lt;/code&gt; file for styling.&lt;/p&gt;

&lt;p&gt;To test the Video Carousel, visit &lt;code&gt;localhost:3000&lt;/code&gt; in your browser. &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%2Fjqr7h31w0e1dhf0cfvfy.gif" 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%2Fjqr7h31w0e1dhf0cfvfy.gif" alt="Video Carousel" width="600" height="111"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Creating reusable components is vital to web development. A reusable carousel component can significantly enhance web projects' efficiency and maintainability. You used React and Splide.js in the article to construct a versatile and adaptable carousel component that seamlessly integrates into any web project.&lt;/p&gt;

&lt;p&gt;Following a systematic approach, you demonstrated how to implement fundamental functionality, customize the styling, and incorporate additional features like autoplay and navigation. The result is a dynamic and flexible carousel component that enhances the user experience and adds visual appeal to web projects. &lt;/p&gt;

&lt;p&gt;With the knowledge gained from this article, you can now create your reusable carousel component using React and Splide.js, elevating your web development skills to the next level.&lt;/p&gt;

&lt;h1&gt;
  
  
  References
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://splidejs.com/" rel="noopener noreferrer"&gt;Splidejs Documentation&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://blog.openreplay.com/build-a-reusable-carousel-with-vue-and-splidejs/" rel="noopener noreferrer"&gt;Build A Reusable Carousel With Vue And Splide.Js&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>react</category>
      <category>tutorial</category>
      <category>javascript</category>
      <category>frontend</category>
    </item>
    <item>
      <title>How to Build and Publish Your First React NPM Package</title>
      <dc:creator>Femi Akinyemi</dc:creator>
      <pubDate>Fri, 09 Jun 2023 18:47:29 +0000</pubDate>
      <link>https://dev.to/femi_akinyemi/how-to-build-and-publish-your-first-react-npm-package-24o3</link>
      <guid>https://dev.to/femi_akinyemi/how-to-build-and-publish-your-first-react-npm-package-24o3</guid>
      <description>&lt;p&gt;Building and publishing your first &lt;a href="https://www.npmjs.com/" rel="noopener noreferrer"&gt;Node Package Manager(NPM)&lt;/a&gt; is an exciting milestone in your journey as a developer. NPM has revolutionized how you share and reuse code in the JavaScript ecosystem, empowering developers to contribute to the open-source community and enhance the efficiency of their projects.&lt;/p&gt;

&lt;p&gt;Whether you want to create a reusable library, a command-line tool, or any other piece of code that can be easily installed and integrated into projects, this article will guide you through the essential steps of building and publishing your first NPM package.&lt;/p&gt;

&lt;h1&gt;
  
  
  Prerequisites
&lt;/h1&gt;

&lt;p&gt;To fully grasp the concepts presented in this tutorial, the following are required:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com" rel="noopener noreferrer"&gt;A GitHub account&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://nodejs.org/en/" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt; ( v10+) installed&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.npmjs.com" rel="noopener noreferrer"&gt;NPM account created&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Basic understanding of JavaScript&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  What is NPM
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://www.npmjs.com/" rel="noopener noreferrer"&gt;NPM&lt;/a&gt; is a powerful tool transforming how developers share and manage JavaScript code. It is the default package manager for &lt;a href="https://nodejs.org/en" rel="noopener noreferrer"&gt;Node&lt;/a&gt;&lt;a href="https://nodejs.org/en" rel="noopener noreferrer"&gt;.js&lt;/a&gt;, a popular runtime environment for executing JavaScript code outside a web browser. NPM is a vast repository of over a million packages, offering developers access to a wide range of open-source libraries, frameworks, and tools.&lt;/p&gt;

&lt;p&gt;With NPM, developers can easily install, update, and manage dependencies for their projects, streamlining the development process and saving valuable time. Whether you need to integrate third-party libraries or share your code with the community, NPM provides a centralized platform for discovering, distributing, and collaborating on JavaScript packages.&lt;/p&gt;

&lt;h1&gt;
  
  
  What are you building
&lt;/h1&gt;

&lt;p&gt;This article explains the process of building and publishing a React NPM package rather than creating an elaborate or complex package. Following the steps outlined in a simple example like the one you'll build, you'll develop a solid foundation to apply the same principles to more advanced packages.&lt;/p&gt;

&lt;p&gt;In this article, you will build a package called &lt;code&gt;capitalizefirstletterofastring&lt;/code&gt;. As the name suggests, this package capitalizes the first letter in a string. It is an excellent place to understand the essential steps in building and publishing an NPM package. So let's dive in and explore the process of creating and publishing your &lt;code&gt;capitalizefirstletterofastring&lt;/code&gt; package.&lt;/p&gt;

&lt;h1&gt;
  
  
  Getting Started
&lt;/h1&gt;

&lt;p&gt;To begin, you need to prepare your environment. A few ways to build a React package include tools like &lt;a href="https://bit.dev" rel="noopener noreferrer"&gt;Bit&lt;/a&gt;, &lt;a href="https://storybook.js.org/" rel="noopener noreferrer"&gt;Storybook&lt;/a&gt;, &lt;a href="https://lerna.js.org/" rel="noopener noreferrer"&gt;Lerna&lt;/a&gt;, and &lt;a href="https://github.com/jaredpalmer/tsdx#quick-start" rel="noopener noreferrer"&gt;TSDX&lt;/a&gt;. However, for this tutorial, you will use a zero-configuration bundler for tiny modules called &lt;a href="https://github.com/developit/microbundle" rel="noopener noreferrer"&gt;Microbundle&lt;/a&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  Why microbundle?
&lt;/h2&gt;

&lt;p&gt;With &lt;a href="https://github.com/developit/microbundle" rel="noopener noreferrer"&gt;Microbundle&lt;/a&gt;, tiny modules can be bundled without any configuration, and it offers the following features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Single dependency for bundling with just a &lt;code&gt;package.json&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;ESnext &amp;amp; async/await support through &lt;a href="https://babeljs.io/" rel="noopener noreferrer"&gt;Babel&lt;/a&gt; and &lt;a href="https://github.com/rpetrich/babel-plugin-transform-async-to-promises" rel="noopener noreferrer"&gt;async-promises&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Produce highly optimized code for all inputs &lt;/li&gt;
&lt;li&gt;Zero-configuration TypeScript support &lt;/li&gt;
&lt;li&gt;Includes built-in Terser compression and tracks gzipped bundle size &lt;/li&gt;
&lt;li&gt;Creates multiple output formats for each entry &lt;em&gt;(CJS, UMD &amp;amp; ESM)&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Supports multiple entry modules &lt;em&gt;(&lt;/em&gt;&lt;code&gt;*cli.js*&lt;/code&gt; &lt;em&gt;+&lt;/em&gt; &lt;code&gt;*index.js*&lt;/code&gt;&lt;em&gt;, etc)&lt;/em&gt;
# Building the package
## Install microbundle&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To use microbundle, run the command below in your terminal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;npm&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;D&lt;/span&gt; &lt;span class="nx"&gt;microbundle&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The command generates a &lt;code&gt;node_modules&lt;/code&gt; folder in your terminal and a &lt;code&gt;package.json&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;In the &lt;code&gt;package.json&lt;/code&gt;, replace the existing code with the code below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&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;capitalizefirstletterofastringpkg&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;version&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;1.0.0&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;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;module&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;source&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;src/index.js&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;main&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;dist/index.js&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;module&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;dist/index.module.js&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;unpkg&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;dist/index.umd.js&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;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;build&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;microbundle&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;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;microbundle watch&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;devDependencies&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;microbundle&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;^0.15.1&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;repository&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;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;git&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;url&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;git+https://github.com/femakin01/CapitalizeFirstLetterofaString.git&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;The provided &lt;code&gt;package.json&lt;/code&gt; code is a configuration file used in Node.js projects. Here's an explanation of each key-value pair in the code:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;"&lt;/code&gt;&lt;code&gt;name&lt;/code&gt;&lt;code&gt;": "&lt;/code&gt;&lt;code&gt;capitalizefirstletterofastringpkg&lt;/code&gt;&lt;code&gt;"&lt;/code&gt; Specifies the name of the package&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;"version": "1.0.0"&lt;/code&gt;: Indicates the version of the package&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;"type": "module"&lt;/code&gt;: Indicates that the project uses ECMAScript modules&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;"source": "src/index.js"&lt;/code&gt;: Specifies the entry file for the source code&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;"main": "dist/index.js"&lt;/code&gt;: Indicates the main file that will be used when importing the package&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;"module": "dist/index.module.js"&lt;/code&gt;: Specifies the module file that will be used in ECMAScript module systems&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;"unpkg": "dist/index.umd.js"&lt;/code&gt;: Specifies the file to be used in the UMD (Universal Module Definition) format&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;"scripts"&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;"build": "microbundle"&lt;/code&gt;: Executes the &lt;code&gt;microbundle&lt;/code&gt; command to build the package.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;"dev": "microbundle watch"&lt;/code&gt;: Executes the &lt;code&gt;microbundle watch&lt;/code&gt; command to start a development server that watches for changes&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;"devDependencies"&lt;/code&gt;: Lists the development dependencies required for the project. In this case, it includes &lt;code&gt;"microbundle": "^0.15.1"&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;"repository"&lt;/code&gt;: Specifies the repository type and URL of the project&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This &lt;code&gt;package.json&lt;/code&gt; file is specifically configured for the &lt;code&gt;capitalizefirstletterofastring&lt;/code&gt; package, utilizing the &lt;code&gt;microbundle&lt;/code&gt; package for building and watching the code.&lt;/p&gt;

&lt;p&gt;At this point, your new &lt;code&gt;package.json&lt;/code&gt; file should resemble this screenshot and is all set up for local development.&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%2Fb5qit7m73dc09tfpdjzd.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%2Fb5qit7m73dc09tfpdjzd.png" alt="package.json file" width="800" height="356"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Package Development
&lt;/h2&gt;

&lt;p&gt;To create the package that capitalizes the first letter of a string, In the &lt;code&gt;src/index.js&lt;/code&gt; file, paste the code below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Capitalize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;charAt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toUpperCase&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code above exports a concise function named &lt;code&gt;Capitalize&lt;/code&gt; that takes a string input and returns the same string with the first character capitalized. It achieves this by using &lt;code&gt;str.charAt(0).toUpperCase() + str.slice(1)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Next, try it out and build the package by running&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="nx"&gt;npm&lt;/span&gt; &lt;span class="nx"&gt;run&lt;/span&gt; &lt;span class="nx"&gt;build&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Microbundle produces &lt;code&gt;esm&lt;/code&gt;, &lt;code&gt;cjs&lt;/code&gt;, &lt;code&gt;umd&lt;/code&gt; bundles with your code compiled to syntax that works everywhere. &lt;/p&gt;

&lt;h1&gt;
  
  
  Publishing the package
&lt;/h1&gt;

&lt;p&gt;To publish your package, run the following command to authenticate yourself:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="nx"&gt;npm&lt;/span&gt; &lt;span class="nx"&gt;login&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will be prompted to provide your details, provide the required details and hit enter. To test the login's success, enter the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="nx"&gt;npm&lt;/span&gt; &lt;span class="nx"&gt;whoami&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your username should be logged into the CLI.&lt;/p&gt;

&lt;p&gt;Now, you can proceed to publish your package by running the command below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="nx"&gt;npm&lt;/span&gt; &lt;span class="nx"&gt;publish&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that you may not be able to publish the random-number-package if someone else already has a package with the same name in the registry. You can change the package's name to something unique to make it publishable. Check here for guides on naming a package.&lt;/p&gt;

&lt;p&gt;After the publication is done without error, you can visit your account in the NPM registry to see the package.&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%2Fm5n44gimf5utjpnd2s8s.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%2Fm5n44gimf5utjpnd2s8s.png" alt="Published package" width="800" height="678"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Testing the Package
&lt;/h1&gt;

&lt;p&gt;To test the package, bootstrap a Next.js application by running the command below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="nx"&gt;npx&lt;/span&gt; &lt;span class="nx"&gt;create&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;latest&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On installation, you'll see the following prompts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="nx"&gt;What&lt;/span&gt; &lt;span class="nx"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;your&lt;/span&gt; &lt;span class="nx"&gt;project&lt;/span&gt; &lt;span class="nx"&gt;named&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;my&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;
    &lt;span class="nx"&gt;Would&lt;/span&gt; &lt;span class="nx"&gt;you&lt;/span&gt; &lt;span class="nx"&gt;like&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;use&lt;/span&gt; &lt;span class="nx"&gt;TypeScript&lt;/span&gt; &lt;span class="kd"&gt;with&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;No&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;Yes&lt;/span&gt;
    &lt;span class="nx"&gt;Would&lt;/span&gt; &lt;span class="nx"&gt;you&lt;/span&gt; &lt;span class="nx"&gt;like&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;use&lt;/span&gt; &lt;span class="nx"&gt;ESLint&lt;/span&gt; &lt;span class="kd"&gt;with&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;No&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;Yes&lt;/span&gt;
    &lt;span class="nx"&gt;Would&lt;/span&gt; &lt;span class="nx"&gt;you&lt;/span&gt; &lt;span class="nx"&gt;like&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;use&lt;/span&gt; &lt;span class="nx"&gt;Tailwind&lt;/span&gt; &lt;span class="nx"&gt;CSS&lt;/span&gt; &lt;span class="kd"&gt;with&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;No&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;Yes&lt;/span&gt;
    &lt;span class="nx"&gt;Would&lt;/span&gt; &lt;span class="nx"&gt;you&lt;/span&gt; &lt;span class="nx"&gt;like&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;use&lt;/span&gt; &lt;span class="s2"&gt;`src/`&lt;/span&gt; &lt;span class="nx"&gt;directory&lt;/span&gt; &lt;span class="kd"&gt;with&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;No&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;Yes&lt;/span&gt;
    &lt;span class="nx"&gt;Use&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="nc"&gt;Router &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;recommended&lt;/span&gt;&lt;span class="p"&gt;)?&lt;/span&gt; &lt;span class="nx"&gt;No&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;Yes&lt;/span&gt;
    &lt;span class="nx"&gt;Would&lt;/span&gt; &lt;span class="nx"&gt;you&lt;/span&gt; &lt;span class="nx"&gt;like&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;customize&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;alias&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;No&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;Yes&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;After the prompts, &lt;code&gt;create-next-app&lt;/code&gt; will create a folder with your project name and install the required dependencies. Next, navigate to the project directory and install the published package by running the command below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="nx"&gt;npm&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="nx"&gt;capitalizefirstletterofastringpkg&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, in the  &lt;code&gt;src/app/page.js&lt;/code&gt; replace the content with the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Capitalize&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="s1"&gt;capitalizefirstletterofastringpkg&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="kd"&gt;function&lt;/span&gt;    &lt;span class="nf"&gt;page&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;  &lt;span class="s2"&gt;`This is  a Sample Usuage {&amp;lt;Capitalize str={'example'} /&amp;gt;}`&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you navigate to &lt;code&gt;localhost:3000&lt;/code&gt;, you will see the first letter of the string in your package capitalized.&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%2Ftglwukndq4gh823faut3.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%2Ftglwukndq4gh823faut3.png" alt="Sample package" width="798" height="104"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Congratulations! You have just successfully created your first React NPM package professionally.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Creating your React component library is a valuable investment for teams or individuals seeking to streamline their development process and ensure project consistency. Following the steps detailed in this guide, you can effortlessly build a library of reusable components that can be shared and utilized across various projects.&lt;br&gt;
Leveraging the capabilities of React and the flexibility of custom components, the possibilities are endless in terms of what you can create and achieve. &lt;br&gt;
Begin constructing your component library today and experience its positive influence on your development workflow!&lt;/p&gt;

&lt;h1&gt;
  
  
  References
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/transitive-bullshit/create-react-library#readme" rel="noopener noreferrer"&gt;Create react library documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/the-andela-way/build-and-publish-your-first-npm-package-a4daf0e2431" rel="noopener noreferrer"&gt;Build and publish your first NPM package&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.openreplay.com/how-to-build-your-own-react-components-library/" rel="noopener noreferrer"&gt;How To Build Your Own React Components Library&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>react</category>
      <category>npm</category>
      <category>javascript</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
