<?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: Tanvir Ahammed</title>
    <description>The latest articles on DEV Community by Tanvir Ahammed (@tanvir8321).</description>
    <link>https://dev.to/tanvir8321</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F546647%2Fc7421a43-ec1f-4499-b474-857ae29e8970.jpeg</url>
      <title>DEV Community: Tanvir Ahammed</title>
      <link>https://dev.to/tanvir8321</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tanvir8321"/>
    <language>en</language>
    <item>
      <title>Fixing React Router Pagination Issue: How to Update URL Params with Buttons Instead of Links</title>
      <dc:creator>Tanvir Ahammed</dc:creator>
      <pubDate>Sun, 27 Apr 2025 09:59:55 +0000</pubDate>
      <link>https://dev.to/tanvir8321/fixing-react-router-pagination-issue-how-to-update-url-params-with-buttons-instead-of-links-598c</link>
      <guid>https://dev.to/tanvir8321/fixing-react-router-pagination-issue-how-to-update-url-params-with-buttons-instead-of-links-598c</guid>
      <description>&lt;h3&gt;
  
  
  Hey Buddy,
&lt;/h3&gt;

&lt;p&gt;I recently ran into a problem while building pagination for a table in a React app. My goal was to have pagination state (like &lt;code&gt;page&lt;/code&gt; and &lt;code&gt;pageSize&lt;/code&gt;) persist in the URL so the page doesn’t reset on refresh. You know, so if the user navigates away and comes back, they can see the same page of results they left off on. Easy, right? But &lt;strong&gt;React Router's &lt;code&gt;Link&lt;/code&gt;&lt;/strong&gt; component was causing me some trouble, so I had to come up with a workaround.&lt;/p&gt;

&lt;p&gt;Let me walk you through what I encountered and how I solved it.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Issue
&lt;/h3&gt;

&lt;p&gt;I had a simple table with pagination. The idea was to update the URL whenever the user changed pages or adjusted the page size. This would make the table "bookmarkable" (i.e., a user could copy-paste the URL and return to the exact same page). Here's the catch: &lt;strong&gt;When using &lt;code&gt;Link&lt;/code&gt; to update the page number in the URL, it wasn't working properly&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;React Router’s &lt;code&gt;Link&lt;/code&gt; is great for navigation, but when you try to control it manually (for example, using &lt;code&gt;onClick&lt;/code&gt; to change URL params), it doesn’t handle everything the way I expected. Specifically, when I used &lt;code&gt;Link&lt;/code&gt; to trigger pagination changes (like moving to the next page or switching page sizes), the &lt;strong&gt;URL didn’t update as expected&lt;/strong&gt;, and the page didn’t reflect the right data.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Solution
&lt;/h3&gt;

&lt;p&gt;The solution was to ditch &lt;code&gt;Link&lt;/code&gt; for the pagination buttons and instead use a &lt;strong&gt;button with &lt;code&gt;navigate()&lt;/code&gt;&lt;/strong&gt; from &lt;code&gt;react-router-dom&lt;/code&gt; to manually handle the URL update.&lt;/p&gt;

&lt;p&gt;Let’s break this down step-by-step.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Create a Custom Hook for URL Params
&lt;/h3&gt;

&lt;p&gt;First, I created a custom hook &lt;code&gt;usePaginationParams&lt;/code&gt; that would handle updating the URL params based on the page and page size:&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;useNavigate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useLocation&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-router-dom&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;usePaginationParams&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;navigate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useNavigate&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;location&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useLocation&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;updatePaginationParams&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pageSize&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;params&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;URLSearchParams&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;search&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;page&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;undefined&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;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;page&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pageSize&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;undefined&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;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pageSize&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pageSize&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;newPath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pathname&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;params&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="s2"&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;newPath&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// Debugging: log the new URL&lt;/span&gt;

    &lt;span class="nf"&gt;navigate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;  &lt;span class="c1"&gt;// Update the URL without reloading the page&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;updatePaginationParams&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;usePaginationParams&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Handling Pagination and Updating the URL
&lt;/h3&gt;

&lt;p&gt;Next, I had to handle pagination in the table and update the URL whenever the user changed the page or page size. Instead of using &lt;code&gt;Link&lt;/code&gt; for pagination buttons, I used a regular &lt;code&gt;button&lt;/code&gt; and directly called &lt;code&gt;navigate()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here’s the relevant part of the code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;TableContainer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;columns&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;total&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pageIndex&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;setPagination&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;customPageSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;updatePaginationParams&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;usePaginationParams&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;currentPage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCurrentPage&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pageIndex&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Handle page change&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handlePageChange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newPage&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setCurrentPage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newPage&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;updatePaginationParams&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;page&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;newPage&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="na"&gt;pageSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;customPageSize&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="nf"&gt;setPagination&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newPage&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// Update pagination state&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="c1"&gt;// Calculate pagination details&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;totalPages&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;ceil&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;total&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;customPageSize&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;
          &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;handlePageChange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;currentPage&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="na"&gt;disabled&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;currentPage&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          Previous
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;totalPages&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;
            &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
            &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;handlePageChange&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="si"&gt;}&lt;/span&gt;
            &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;currentPage&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;active&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="si"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;
          &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;handlePageChange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;currentPage&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="na"&gt;disabled&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;currentPage&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;totalPages&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          Next
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Explanation of the Fix
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;updatePaginationParams&lt;/code&gt;&lt;/strong&gt;: This function is responsible for updating the URL with the new &lt;code&gt;page&lt;/code&gt; and &lt;code&gt;pageSize&lt;/code&gt; whenever the user navigates to a different page.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;navigate()&lt;/code&gt;&lt;/strong&gt;: Instead of using &lt;code&gt;Link&lt;/code&gt; components, we directly call &lt;code&gt;navigate()&lt;/code&gt; (from &lt;code&gt;react-router-dom&lt;/code&gt;) to update the URL and avoid page reloads. This is what allows the page URL to stay in sync with the table's current state.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Buttons for Pagination&lt;/strong&gt;: I replaced &lt;code&gt;Link&lt;/code&gt; components with regular buttons (&lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt;). These buttons trigger the URL change using &lt;code&gt;handlePageChange&lt;/code&gt;, which updates both the state of the page and the URL params. The &lt;code&gt;disabled&lt;/code&gt; attribute prevents users from navigating beyond the available pages.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;State Handling&lt;/strong&gt;: The &lt;code&gt;currentPage&lt;/code&gt; state keeps track of the active page, ensuring that the page navigation buttons reflect the current page in the UI.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Why This Works
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;Link&lt;/code&gt; vs Button&lt;/strong&gt;: &lt;code&gt;Link&lt;/code&gt; was not working as expected with &lt;code&gt;onClick&lt;/code&gt; handlers for pagination because it’s built to handle navigation on its own. Adding custom behavior with &lt;code&gt;onClick&lt;/code&gt; might interfere with its internal logic, especially when you’re trying to manipulate URL params manually.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;navigate()&lt;/code&gt;&lt;/strong&gt;: The &lt;code&gt;navigate()&lt;/code&gt; function from &lt;code&gt;react-router-dom&lt;/code&gt; is designed to update the URL &lt;strong&gt;without reloading the page&lt;/strong&gt;. It’s exactly what we needed for our pagination because it allows us to change the URL params while keeping the user on the same page (without triggering a full reload).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Control over the URL&lt;/strong&gt;: Using &lt;code&gt;navigate()&lt;/code&gt; directly allows us full control over the URL and ensures it reflects the current page and page size, which is crucial for bookmarking and sharing URLs.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;By replacing &lt;code&gt;Link&lt;/code&gt; with &lt;code&gt;button&lt;/code&gt; and using &lt;code&gt;navigate()&lt;/code&gt; for manual URL updates, I was able to fix the pagination issue and ensure the URL stays in sync with the pagination state. It was a simple but effective solution, and it works seamlessly in React Router.&lt;/p&gt;

&lt;p&gt;Now, when a user changes pages, the URL is updated accordingly, and the state persists even if the page is refreshed. I’m sharing this with you in case you run into a similar issue in your projects!&lt;/p&gt;

&lt;p&gt;Hope this helps!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How I Solved the "MySQL Shutdown Unexpectedly" Error: A Step-by-Step Guide</title>
      <dc:creator>Tanvir Ahammed</dc:creator>
      <pubDate>Sat, 30 Nov 2024 10:29:09 +0000</pubDate>
      <link>https://dev.to/tanvir8321/how-i-solved-the-mysql-shutdown-unexpectedly-error-a-step-by-step-guide-2nke</link>
      <guid>https://dev.to/tanvir8321/how-i-solved-the-mysql-shutdown-unexpectedly-error-a-step-by-step-guide-2nke</guid>
      <description>&lt;p&gt;It's frustratingly annoying to experience the hated &lt;strong&gt;MySQL shutdown unexpectedly&lt;/strong&gt; error when working with MySQL-especially if your development projects depend on it.&lt;/p&gt;

&lt;p&gt;If you've been working on a project and suddenly faced the &lt;strong&gt;MySQL shutdown unexpectedly&lt;/strong&gt; error, you're not alone. This issue can arise for many reasons, but in my case, after hours of debugging, I discovered the root cause: &lt;strong&gt;Physically writing the file full.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Fixed the Error
&lt;/h2&gt;

&lt;p&gt;After extensive research and testing, I followed a methodical approach to repair the corrupted data files. Here's the step-by-step solution:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Navigate to the Data Directory&lt;/strong&gt;&lt;br&gt;
The first step is locating the MySQL data directory where all database files are stored. In XAMPP, this is usually:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;C:\xampp\mysql\data\&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Backup the Data&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before making any changes, it’s crucial to &lt;strong&gt;back up your files&lt;/strong&gt; to prevent accidental data loss:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Copy all files from the &lt;code&gt;C:\xampp\mysql\data\&lt;/code&gt; directory.&lt;/li&gt;
&lt;li&gt;Save them in a safe location as your backup.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. Delete Corrupted Files&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Next, remove the specific files causing the issue:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Delete all files with the name pattern &lt;code&gt;aria_log.######## (e.g., aria_log.00000001)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Delete the ibtmp1 file in the same directory.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: These files are often temporary or log files that can be regenerated when MySQL restarts.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;4. Restart MySQL&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once you've completed the steps above, &lt;strong&gt;restart MySQL&lt;/strong&gt; from the XAMPP Control Panel. If everything went well, the server should start without any issues.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Solution Works
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Aria Logs:&lt;/strong&gt; Deleting the &lt;code&gt;aria_log.########&lt;/code&gt; files removes any corrupted log data that may hinder MySQL's startup process.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Debugging MySQL errors&lt;/strong&gt; can be a challenging task, but with patience and the right approach, most issues are solvable. By repairing corrupted data files and cleaning up unnecessary logs, I was able to fix the "&lt;strong&gt;MySQL shutdown unexpectedly&lt;/strong&gt;" error and continue working on my project without interruptions.&lt;/p&gt;

&lt;p&gt;If you're facing the same issue, I hope &lt;strong&gt;this guide helps you&lt;/strong&gt; resolve it quickly. Don't forget to &lt;strong&gt;back up your data&lt;/strong&gt; regularly to prevent future headaches!&lt;/p&gt;

</description>
      <category>mysql</category>
      <category>mariadb</category>
      <category>help</category>
      <category>database</category>
    </item>
    <item>
      <title>Keyword Research Tools to Boost Your SEO Strategy</title>
      <dc:creator>Tanvir Ahammed</dc:creator>
      <pubDate>Sat, 30 Nov 2024 08:20:21 +0000</pubDate>
      <link>https://dev.to/tanvir8321/keyword-research-tools-to-boost-your-seo-strategy-1j68</link>
      <guid>https://dev.to/tanvir8321/keyword-research-tools-to-boost-your-seo-strategy-1j68</guid>
      <description>&lt;p&gt;Keyword research is &lt;strong&gt;the backbone&lt;/strong&gt; of a good SEO strategy. It helps you identify what your audience is looking for and allows you to create content that resonates with their needs. But when there are so &lt;strong&gt;many tools available&lt;/strong&gt; for keyword research, how do you choose one that will help you &lt;strong&gt;reach your goal&lt;/strong&gt;? &lt;/p&gt;

&lt;p&gt;In this post, we identify some of the best and how they can &lt;strong&gt;boost your SEO content&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Keyword Research Matters
&lt;/h2&gt;

&lt;p&gt;Keyword research is more than just finding popular search terms. It's about-&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Identifying your audience's intent.&lt;/li&gt;
&lt;li&gt;Understanding the competition.&lt;/li&gt;
&lt;li&gt;Find opportunities ranking for niche topics.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With the right tools, you can uncover insights that lead to better content, improved rankings, and more organic traffic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Top Keyword Research Tools
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Google Keyword Planner&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A free and beginner-friendly tool, Google Keyword Planner is perfect for those just starting with SEO. It provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Search volume and competition data.&lt;/li&gt;
&lt;li&gt;Keyword ideas based on your niche.&lt;/li&gt;
&lt;li&gt;Insights into seasonal trends.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2.  SEMrush&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;SEMrush is a powerhouse for SEO professionals. Its keyword research features include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Detailed keyword difficulty scores.&lt;/li&gt;
&lt;li&gt;Competitor analysis.&lt;/li&gt;
&lt;li&gt;Related keywords and phrase matches.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. Ahrefs Keywords Explorer&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ahrefs is another industry favorite. It offers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In-depth keyword metrics like clicks and return rates.&lt;/li&gt;
&lt;li&gt;Global search data for multiple countries.&lt;/li&gt;
&lt;li&gt;Comprehensive competitor research.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;4. Ubersuggest&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Created by Neil Patel, Ubersuggest is great for small businesses and startups. Key features include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keyword suggestions and search volume data.&lt;/li&gt;
&lt;li&gt;Backlink analysis.&lt;/li&gt;
&lt;li&gt;Easy-to-read reports for beginners.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;5. Moz Keyword Explorer&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Moz provides actionable insights with its user-friendly interface. Features include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keyword difficulty scores.&lt;/li&gt;
&lt;li&gt;Organic CTR (Click-Through Rate) analysis.&lt;/li&gt;
&lt;li&gt;Prioritized suggestions based on your goals.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to Choose the Right Tool
&lt;/h2&gt;

&lt;p&gt;Not all tools are created equal, and your choice depends on your specific needs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Budget: If you’re on a tight budget, tools like Google Keyword Planner and Ubersuggest are great starting points.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Depth of Analysis: For advanced research, tools like Ahrefs or SEMrush provide comprehensive data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ease of Use: Beginners might prefer simpler tools like Ubersuggest or Moz.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Pro Tips for Effective Keyword Research
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Focus on Long-Tail Keywords: These are less competitive and more targeted.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Analyze Your Competitors: Use tools to see which keywords they rank for and identify gaps.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Track and Update Regularly: Keyword trends change, so revisit your research periodically.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Keyword research tools are essential for building a strong SEO foundation. Whether you’re a beginner or an experienced marketer, the right tool can help you uncover valuable insights to drive your strategy forward.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which keyword research tool is your favorite? Let me know in the comments, and don’t forget to share this post if you found it helpful!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>seo</category>
      <category>contentwriting</category>
      <category>blogpost</category>
      <category>technicalwring</category>
    </item>
    <item>
      <title>Building a File Upload API with Next.js and Google Drive Integration</title>
      <dc:creator>Tanvir Ahammed</dc:creator>
      <pubDate>Wed, 27 Dec 2023 07:17:56 +0000</pubDate>
      <link>https://dev.to/tanvir8321/building-a-file-upload-api-with-nextjs-and-google-drive-integration-fh1</link>
      <guid>https://dev.to/tanvir8321/building-a-file-upload-api-with-nextjs-and-google-drive-integration-fh1</guid>
      <description>&lt;p&gt;In this tutorial, we'll walk through the process of creating a serverless API using Next.js that allows users to upload files directly to Google Drive. We'll use the Google Drive API for file storage and Next.js for the serverless API endpoints.&lt;/p&gt;

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

&lt;p&gt;Before getting started, make sure you have the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;- A Google Cloud Platform (GCP) project with the &lt;a href="https://youtu.be/bkaQTLCBBeo" rel="noopener noreferrer"&gt;Google Drive API enabled.&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;- API credentials in the form of a service account key (JSON file).&lt;/li&gt;
&lt;li&gt;- Node.js and npm installed on your development machine.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Setting Up the Project
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Initialize a Next.js Project:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx create-next-app my-drive-api
cd my-drive-api
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Install Dependencies:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install googleapis multer stream
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Api Code
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// pages/api/googleDrive.js
import { google } from "googleapis";
const stream = require("stream");
import multer from "multer";
const apikeys = require("./apikeys.json");
const SCOPE = ["https://www.googleapis.com/auth/drive"];

export const config = {
  api: {
    bodyParser: false,
  },
};

// Function to authorize the Google Drive API
async function authorize() {
  const jwtClient = new google.auth.JWT(
    apikeys.client_email,
    null,
    apikeys.private_key,
    SCOPE
  );

  await jwtClient.authorize();

  return jwtClient;
}

// Multer storage configuration
const storage = multer.memoryStorage();
const upload = multer({ storage: storage });

// API endpoint handler
export default async function handler(req: any, res: any) {
  if (req.method !== "POST") {
    return res.status(405).end(); // Method Not Allowed
  }

  try {
    await new Promise&amp;lt;void&amp;gt;((resolve, reject) =&amp;gt; {
      upload.single("image")(req as any, res as any, (err) =&amp;gt; {
        if (err) {
          return reject(err); // Reject if multer encounters an error
        }
        resolve();
      });
    });

    const uploadedFile = req.file;

    if (!uploadedFile) {
      return res.status(400).json({ error: "No file uploaded" });
    }

    const authClient = await authorize();
    const result: any = await uploadFile(authClient, uploadedFile);

    // Wait for a short delay (e.g., 2 seconds) before responding
    await new Promise((resolve) =&amp;gt; setTimeout(resolve, 2000));

    const previewLink = `https://drive.google.com/uc?id=${result?.data?.id}`;

    res.status(200).json({ previewLink, id: result?.data?.id });
  } catch (error: any) {
    console.error(error);
    res.status(500).json({ error: error?.message ?? "Internal Server Error" });
  }
}

// Function to upload a file to Google Drive
async function uploadFile(authClient: any, uploadedFile: any) {
  return new Promise((resolve, reject) =&amp;gt; {
    const drive = google.drive({ version: "v3", auth: authClient });

    const fileMetaData = {
      name: uploadedFile.originalname,
      parents: ["1rE3jBXCsPoABRPCyHhvHBqH9SxzzFzCm"],
    };

    drive.files.create(
      {
        resource: fileMetaData,
        media: {
          mimeType: uploadedFile.mimetype,
          body: stream.PassThrough().end(uploadedFile.buffer),
        },
        fields: "id",
      },
      (error: any, file: any) =&amp;gt; {
        if (error) {
          return reject(error); // Reject if there's an error during file creation
        }

        // Set permissions to make the file public
        drive.permissions.create(
          {
            fileId: file.data.id,
            requestBody: {
              role: "reader",
              type: "anyone",
            },
          },
          (err: any) =&amp;gt; {
            if (err) {
              console.error(err);
              return reject(err); // Reject if there's an error setting permissions
            }
            resolve(file);
          }
        );
      }
    );
  });
}

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

&lt;/div&gt;



</description>
      <category>googlecloud</category>
      <category>nextjs</category>
      <category>api</category>
    </item>
    <item>
      <title>Image upload by NextJs Api in Public Folder</title>
      <dc:creator>Tanvir Ahammed</dc:creator>
      <pubDate>Wed, 27 Dec 2023 05:02:58 +0000</pubDate>
      <link>https://dev.to/tanvir8321/image-upload-by-nextjs-api-in-public-folder-14gp</link>
      <guid>https://dev.to/tanvir8321/image-upload-by-nextjs-api-in-public-folder-14gp</guid>
      <description>&lt;p&gt;** FIRST ENSURE THAT YOU HAVE NEXT JS PROJECT**&lt;/p&gt;

&lt;h2&gt;
  
  
  THEN INSTALL THESE PACKAGE
&lt;/h2&gt;



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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;BACK-END&lt;/strong&gt;&lt;br&gt;
api\upload.ts&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { NextApiRequest, NextApiResponse } from "next";
import multer from "multer";
import path from "path";
export const config = {
  api: {
    bodyParser: false,
  },
};
const storage = multer.diskStorage({
  destination: (req, file, cb) =&amp;gt; {
    const dateFolder = new Date().toISOString().split("T")[0]; // Use date as the folder name
    const uploadPath = path.join("./public/uploads", dateFolder);

    // Create the folder if it doesn't exist
    require("fs").mkdirSync(uploadPath, { recursive: true });

    cb(null, uploadPath);
  },
  filename: (req, file, cb) =&amp;gt; {
    cb(
      null,
      `${file.fieldname}-${Date.now()}${file.originalname.substring(
        file.originalname.lastIndexOf(".")
      )}`
    );
  },
});

const upload = multer({ storage });

const uploadApi = async (req: NextApiRequest, res: NextApiResponse) =&amp;gt; {
  try {
    await new Promise&amp;lt;void&amp;gt;((resolve, reject) =&amp;gt; {
      upload.single("image")(req as any, res as any, (err) =&amp;gt; {
        if (err) {
          return reject(err);
        }
        resolve();
      });
    });

    // Access the 'file' property after the multer middleware processes the file
    const uploadedFile = req.file;

    if (!uploadedFile) {
      return res.status(400).json({ error: "No file uploaded" });
    }

    // Assuming the uploaded file is saved in the public/uploads folder
    const dateFolder = new Date().toISOString().split("T")[0];
    const fileName = uploadedFile.filename;
    const filePath = path.join("uploads", dateFolder, fileName);

    res.status(200).json({ message: "Image uploaded successfully", filePath });
  } catch (error) {
    console.log(error);

    res.status(500).json({ error: "Error uploading image" });
  }
};

export default uploadApi;

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

&lt;/div&gt;



&lt;p&gt;next.config.js&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;async rewrites() {
    return [
      {
        source: "/uploads/:path*",
        destination: "/uploads/:path*", // Adjust this path based on your project structure
      },
    ];
  },
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;** FRONT-END **&lt;br&gt;
components\UploadForm.tsx&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Your React component

import React, { useState } from "react";

const UploadForm = () =&amp;gt; {
  const [file, setFile] = useState&amp;lt;any&amp;gt;(null);

  const handleFileChange = (e: any) =&amp;gt; {
    setFile(e.target.files[0]);
  };

  const handleUpload = async () =&amp;gt; {
    const formData = new FormData();
    formData.append("image", file);

    try {
      const response = await fetch("/api/upload", {
        method: "POST",
        body: formData,
      });

      if (response.ok) {
        // Parse the JSON response
        const responseData = await response.json();

        // Access the data from the server
        console.log("Image uploaded successfully", responseData);
      } else {
        console.error("Error uploading image");
      }
    } catch (error) {
      console.error("Error uploading image", error);
    }
  };

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;input type="file" onChange={handleFileChange} /&amp;gt;
      &amp;lt;button onClick={handleUpload}&amp;gt;Upload&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

export default UploadForm;

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  FRONT-END UI
&lt;/h2&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%2Fpwehsilsqnuknwjfdg1z.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%2Fpwehsilsqnuknwjfdg1z.PNG" alt="Uploaded image with a response" width="800" height="243"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  BACK-END UPLOADED FOLDER
&lt;/h2&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%2Fqdg5uerwp6aai8fsf51o.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%2Fqdg5uerwp6aai8fsf51o.PNG" alt="Image uploaded folder" width="404" height="413"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>nextjsapi</category>
      <category>programming</category>
      <category>typescript</category>
    </item>
    <item>
      <title>How to set YouTube Video as Background in the Next.JS/React.Js app with styled component?</title>
      <dc:creator>Tanvir Ahammed</dc:creator>
      <pubDate>Tue, 19 Sep 2023 10:33:49 +0000</pubDate>
      <link>https://dev.to/tanvir8321/how-to-set-youtube-video-as-background-in-the-nextjsreactjs-app-with-styled-component-a7i</link>
      <guid>https://dev.to/tanvir8321/how-to-set-youtube-video-as-background-in-the-nextjsreactjs-app-with-styled-component-a7i</guid>
      <description>&lt;p&gt;VideoBackground.tsx&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";
import styled from "styled-components";

const VIDEO_WIDTH = 1920;
const VIDEO_HEIGHT = 1080;

const VideoBackgroundWrapper = styled.div`
  position: relative;
  overflow: hidden;
  width: 100vw;
  height: 100vh;

  @media (min-aspect-ratio: 16/9) {
    --video-height: 56.25vw;
  }

  @media (max-aspect-ratio: 16/9) {
    --video-width: 177.78vh;
  }
`;

const VideoIframe = styled.iframe`
  position: absolute;
  top: 50%;
  left: 50%;
  width: var(--video-width, ${VIDEO_WIDTH}px);
  height: var(--video-height, ${VIDEO_HEIGHT}px);
  transform: translate(-50%, -50%);
`;

export const VideoBackground = ({ videoId, className }: any) =&amp;gt; {
  const yt = `https://www.youtube.com/embed/${videoId}?autoplay=1&amp;amp;controls=0&amp;amp;mute=1&amp;amp;loop=1&amp;amp;modestbranding=1&amp;amp;showinfo=0&amp;amp;enablejsapi=1&amp;amp;&amp;amp;widgetid=3&amp;amp;playlist=${videoId}`;
  return (
    &amp;lt;VideoBackgroundWrapper className={className ?? ""}&amp;gt;
      &amp;lt;VideoIframe
        width={VIDEO_WIDTH}
        height={VIDEO_HEIGHT}
        src={yt}
        title="YouTube video player"
        frameBorder="0"
        allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
      /&amp;gt;
    &amp;lt;/VideoBackgroundWrapper&amp;gt;
  );
};

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

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app.tsx
export default function App() {
  return (
    &amp;lt;div className="video-layer"&amp;gt;
      &amp;lt;VideoBackground
        className="image-layer"
        videoId={data?.videoId ?? "PtDIVU_tlo0"}
      /&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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