react-paginate
react-paginate copied to clipboard
Render issues on Next.js 13.5.4 after upgrading from 13.4.12
Bumped up my version of Next.js to silence a vulnerability notice, and after doing so react-paginate no longer works correctly. Getting around it for now by locking my version to 13.4.12, but not a fan of this solution.
Expected behaviour (on 13.4.12):
<ul class="pagination col-span-full gap-3 flex justify-center font-bold my-16" role="navigation" aria-label="Pagination">
<li class="previous disabled"><a class="h-full flex items-center rotate-180 mr-5 " tabindex="-1" role="button" aria-disabled="true" aria-label="Previous page" rel="prev"><img alt="Previous Page" loading="lazy" width="15" height="9" decoding="async" data-nimg="1" class="inline-block" style="color: transparent;" src="/_next/static/media/icon-arrow-right.0ababecc.svg"></a></li>
<li class="selected"><a rel="canonical" role="button" class="flex font-black" tabindex="-1" aria-label="Page 1 is your current page" aria-current="page">1</a></li>
<li><a rel="next" role="button" class="flex" tabindex="0" aria-label="Page 2">2</a></li>
<li><a role="button" class="flex" tabindex="0" aria-label="Page 3">3</a></li>
<li><a role="button" class="flex" tabindex="0" aria-label="Page 4">4</a></li>
<li class="break"><a role="button" tabindex="0" aria-label="Jump forward">...</a></li>
<li><a role="button" class="flex" tabindex="0" aria-label="Page 13">13</a></li>
<li class="next"><a class="h-full flex items-center ml-5" tabindex="0" role="button" aria-disabled="false" aria-label="Next page" rel="next"><img alt="Next Page" loading="lazy" width="15" height="9" decoding="async" data-nimg="1" class="inline-block" style="color: transparent;" src="/_next/static/media/icon-arrow-right.0ababecc.svg"></a></li>
</ul>
What happens (on 13.5.4):
<ul class="pagination col-span-full gap-3 flex justify-center font-bold my-16" role="navigation" aria-label="Pagination">
<li class="previous disabled"><a class="h-full flex items-center rotate-180 mr-5 " tabindex="-1" role="button" aria-disabled="true" aria-label="Previous page" rel="prev"><img alt="Previous Page" loading="lazy" width="15" height="9" decoding="async" data-nimg="1" class="inline-block" style="color: transparent;" src="/_next/static/media/icon-arrow-right.0ababecc.svg"></a></li>
<ul role="navigation" aria-label="Pagination">
<li class="previous disabled"><a class=" " tabindex="-1" role="button" aria-disabled="true" aria-label="Previous page" rel="prev">Previous</a></li>
<li class="next"><a class="" tabindex="0" role="button" aria-disabled="false" aria-label="Next page" rel="next">Next</a></li>
</ul>
<ul role="navigation" aria-label="Pagination">
<li class="previous disabled"><a class=" " tabindex="-1" role="button" aria-disabled="true" aria-label="Previous page" rel="prev">Previous</a></li>
<li class="next"><a class="" tabindex="0" role="button" aria-disabled="false" aria-label="Next page" rel="next">Next</a></li>
</ul>
<ul role="navigation" aria-label="Pagination">
<li class="previous disabled"><a class=" " tabindex="-1" role="button" aria-disabled="true" aria-label="Previous page" rel="prev">Previous</a></li>
<li class="next"><a class="" tabindex="0" role="button" aria-disabled="false" aria-label="Next page" rel="next">Next</a></li>
</ul>
<ul role="navigation" aria-label="Pagination">
<li class="previous disabled"><a class=" " tabindex="-1" role="button" aria-disabled="true" aria-label="Previous page" rel="prev">Previous</a></li>
<li class="next"><a class="" tabindex="0" role="button" aria-disabled="false" aria-label="Next page" rel="next">Next</a></li>
</ul>
<li class="break"><a role="button" tabindex="0" aria-label="Jump forward">...</a></li>
<ul role="navigation" aria-label="Pagination">
<li class="previous disabled"><a class=" " tabindex="-1" role="button" aria-disabled="true" aria-label="Previous page" rel="prev">Previous</a></li>
<li class="next"><a class="" tabindex="0" role="button" aria-disabled="false" aria-label="Next page" rel="next">Next</a></li>
</ul>
<li class="next"><a class="h-full flex items-center ml-5" tabindex="0" role="button" aria-disabled="false" aria-label="Next page" rel="next"><img alt="Next Page" loading="lazy" width="15" height="9" decoding="async" data-nimg="1" class="inline-block" style="color: transparent;" src="/_next/static/media/icon-arrow-right.0ababecc.svg"></a></li>
</ul>
Here is the JS of one of the pages that has pagination, if that helps. All instances of ReactPaginate on this site are experiencing this.
import { useEffect, useState } from 'react';
import NextImage from 'next/image';
import ReactPaginate from 'react-paginate';
// assets
import iconArrowRight from '@/images/icon-arrow-right.svg';
// components
import EventList from '@/components/Event/EventsList';
export default function PaginatedEvents({ data }) {
// pagination
const [itemOffset, setItemOffset] = useState(0);
// Simulate fetching items from another resources.
// (This could be items from props; or items loaded in a local state
// from an API endpoint with useEffect and useState)
const events = data;
const itemsPerPage = 6;
const endOffset = itemOffset + itemsPerPage;
const pageCount = Math.ceil(events.length / itemsPerPage);
const currentEvents = events.slice(itemOffset, endOffset);
// Invoke when user click to request another page.
const [currentPage, setCurrentPage] = useState(0);
const handlePageClick = (event) => {
setCurrentPage(event.selected);
const newOffset = (event.selected * itemsPerPage) % events.length;
setItemOffset(newOffset);
};
const Pagination = () => (
<ReactPaginate
onPageChange={handlePageClick}
pageRangeDisplayed={4}
marginPagesDisplayed={1}
pageCount={pageCount}
forcePage={currentPage}
pageLinkClassName='flex'
activeLinkClassName='font-black'
breakLabel='...'
nextLinkClassName='h-full flex items-center ml-5'
nextLabel={
<NextImage
src={iconArrowRight}
className='inline-block'
alt='Next Page'
/>
}
previousLinkClassName='h-full flex items-center rotate-180 mr-5'
previousLabel={
<NextImage
src={iconArrowRight}
className='inline-block'
alt='Previous Page'
/>
}
renderOnZeroPageCount={null}
className={'pagination col-span-full gap-3 flex justify-center font-bold my-16'}
/>
);
useEffect(() => {
const eventList = document.getElementById('event-list');
window.scrollTo({
top: eventList.scrollTop,
behavior: 'smooth',
});
}, [currentPage]);
return (
<div className='event-list' id='event-list'>
<Pagination />
<EventList events={currentEvents} />
<Pagination />
</div>
);
}
Yes, this also happens to me. Not sure why in development it is rendering correctly though. But on my staging env, it renders like this
this is my code
<ReactPaginate
className="flex items-center justify-center"
pageCount={metadata.pageCount}
forcePage={metadata.page - 1}
pageRangeDisplayed={1}
marginPagesDisplayed={1}
onPageChange={({ selected }) => onPageChange((selected += 1))}
breakLabel="..."
breakClassName="h-9 w-9 flex justify-center"
containerClassName={"wif-pagination"}
pageClassName="h-9 w-9 flex justify-center items-center ring-1 ring-inset ring-gray-300 -ml-[1px]"
pageLinkClassName="leading-1"
activeClassName="bg-wif-orange-2 text-white ring-0"
previousClassName="relative inline-flex items-center rounded-l-md p-2 text-gray-400 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:z-20 focus:outline-offset-0"
nextClassName="relative inline-flex items-center rounded-r-md p-2 text-gray-400 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:z-20 focus:outline-offset-0"
previousLabel={
<>
<span className="sr-only">Previous</span>
<svg
className="h-5 w-5"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
>
<path
fillRule="evenodd"
d="M12.79 5.23a.75.75 0 01-.02 1.06L8.832 10l3.938 3.71a.75.75 0 11-1.04 1.08l-4.5-4.25a.75.75 0 010-1.08l4.5-4.25a.75.75 0 011.06.02z"
clipRule="evenodd"
/>
</svg>
</>
}
nextLabel={
<>
<span className="sr-only">Next</span>
<svg
className="h-5 w-5"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
>
<path
fillRule="evenodd"
d="M7.21 14.77a.75.75 0 01.02-1.06L11.168 10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z"
clipRule="evenodd"
/>
</svg>
</>
}
/>
Ya it works fine when I am just running npm run dev, but is broken after a build. So it is something about the build process in 13.5 that is breaking it.
Same thing happening here!
Same issue here.
linked with nextjs update to 13.5.4 (13.5.3 works fine) https://github.com/vercel/next.js/issues/56406
Any update on this issue? Kind of a big problem.
I tracked it down to a specific commit that broke it.
https://github.com/vercel/next.js/commit/83c18deafe4f133f74ef2b1e0512228098d48cba
It has something to do with the SWC minifier. If you set keep_fnames to false in packages/next/src/build/webpack/plugins/terser-webpack-plugin/src/index.ts then this problem goes away.
keep_fnames (default false) -- Pass true to not mangle function names. Pass a regular expression to only keep function names matching that regex. Useful for code relying on Function.prototype.name.
Workaround
You can add swcMinify: false to your next.config.js file. It will go back to using the Terser minifier, which was the default before v13.
@camcamcamcam I've had swcMinify: true in my project since day one without issues. It's odd you have to set it to false now, but I guess that's a workaround for now.
I think it is because they changed the defaults for the SWC minifier in 13.5.4, from the default of keep_fnames: false to keep_fnames: true.
I'm honestly not sure why this affects react-paginate, but it does. It at least does explains why it only happens in builds.
Thanks for creating this issue. I also facing same issue:
Why this happen? Issue happen after upgrade next to version 13.5.4
Here in Dev server:
Here in Prod server:
@camcamcamcam I've had
swcMinify: truein my project since day one without issues. It's odd you have to set it to false now, but I guess that's a workaround for now.
Does it affect for performance? since it is SWC thing
@lutfi-haslab Not in anyway that I have noticed in production, since it is still being minified, just using the pre v13 minifier. The only difference I have noticed, or at least can measure, is that the build take ever so slightly longer.
#504
I have this issue in production too. Kind of a big problem for my company.
Next: 13.5.4
I faced same issue when I updated Next version to 13.5.4. As a temporary solution, I downgraded Next.js to the previous version. However, this is not an ideal solution. I would appreciate it if the issue could be fixed to work correctly with the new version.
I have same issue :)
Having the same issue. Had to use this workaround
I was able to show it again after downgrade to next 13.5.2 and react-paginate 8.1.4 as mention below https://github.com/vercel/next.js/issues/56406#issuecomment-1752461866
I was having the same issue, and just upgrade the next.js version to 15.5.5 (latest version) solved my issue.
It's still broken for v15.5.5 and swcMinify: true.
@ORizzo
I was having the same issue, and just upgrade the next.js version to 15.5.5 (latest version) solved my issue.
which react-paginate version? still broken here like @JavierMartinz ^
@ORizzo
I was having the same issue, and just upgrade the next.js version to 15.5.5 (latest version) solved my issue.
which react-paginate version? still broken here like @JavierMartinz ^
I just updated to [email protected], and trying with both [email protected] and [email protected], and can confirm it is still broken.
Sorry I forgot to send my specs.
Versions: nextjs - 13.5.5 react-paginate: 8.2
Config: nextjs.config.js - swcMinify: false.
Same issue in 13.5.6
swcMinify: false Does the trick but I should not be the solution for the future. Hopefully, there will be a better fix
same issue
Still exists on [email protected]
Same issue in 13.5.6
swcMinify: false Does the trick but I should not be the solution for the future. Hopefully, there will be a better fix
Disabling SWC Minifer will not be an option in the next major version. Please report any issues you may be experiencing to https://github.com/vercel/next.js/issues
For now it works by disabling the "swcMinify" but it will be removed by Next in the future.
Same error
Same issue in 13.5.6 swcMinify: false Does the trick but I should not be the solution for the future. Hopefully, there will be a better fix
Disabling SWC Minifer will not be an option in the next major version. Please report any issues you may be experiencing to https://github.com/vercel/next.js/issues
For now it works by disabling the "swcMinify" but it will be removed by Next in the future.
This actually works, but I don't know if it affects performance the way nextjs described.