swiper
swiper copied to clipboard
[Swiper Element] Server Side Component Support
Clear and concise description of the problem
In a npx create-next-app@latest
boilerplate add this component
'use server'
import { register } from 'swiper/element';
register();
export const Slider = () => {
return (
<div style={{"width": "80vw"}}>
<swiper-container>
<swiper-slide>
<h2>Slide 1</h2>
</swiper-slide>
<swiper-slide>
<h2>Slide 2</h2>
</swiper-slide>
<swiper-slide>
<h2>Slide 3</h2>
</swiper-slide>
</swiper-container>
</div>
);
}
You will receive this error:
Unhandled Runtime Error
Error: Hydration failed because the initial UI does not match what was rendered on the server.
Warning: Expected server HTML to contain a matching <swiper-slide> in <swiper-container>.
See more info here: https://nextjs.org/docs/messages/react-hydration-error
Component Stack
swiper-slide
swiper-container
main
Call Stack
throwOnHydrationMismatch
node_modules/next/dist/compiled/react-dom-experimental/cjs/react-dom.development.js (6956:0)
tryToClaimNextHydratableInstance
node_modules/next/dist/compiled/react-dom-experimental/cjs/react-dom.development.js (6985:0)
updateHostComponent$1
node_modules/next/dist/compiled/react-dom-experimental/cjs/react-dom.development.js (16233:0)
beginWork$1
node_modules/next/dist/compiled/react-dom-experimental/cjs/react-dom.development.js (18133:0)
HTMLUnknownElement.callCallback
node_modules/next/dist/compiled/react-dom-experimental/cjs/react-dom.development.js (20207:0)
Object.invokeGuardedCallbackImpl
node_modules/next/dist/compiled/react-dom-experimental/cjs/react-dom.development.js (20256:0)
invokeGuardedCallback
node_modules/next/dist/compiled/react-dom-experimental/cjs/react-dom.development.js (20331:0)
beginWork
node_modules/next/dist/compiled/react-dom-experimental/cjs/react-dom.development.js (26498:0)
performUnitOfWork
node_modules/next/dist/compiled/react-dom-experimental/cjs/react-dom.development.js (25327:0)
workLoopConcurrent
node_modules/next/dist/compiled/react-dom-experimental/cjs/react-dom.development.js (25313:0)
renderRootConcurrent
node_modules/next/dist/compiled/react-dom-experimental/cjs/react-dom.development.js (25269:0)
performConcurrentWorkOnRoot
node_modules/next/dist/compiled/react-dom-experimental/cjs/react-dom.development.js (24122:0)
workLoop
node_modules/next/dist/compiled/scheduler-experimental/cjs/scheduler.development.js (261:0)
flushWork
node_modules/next/dist/compiled/scheduler-experimental/cjs/scheduler.development.js (230:0)
MessagePort.performWorkUntilDeadline
node_modules/next/dist/compiled/scheduler-experimental/cjs/scheduler.development.js (537:0)
Suggested solution
- split importable modules into template & component
- Remove references to window from potential server-side code
Alternative
No response
Additional context
https://lamplightdev.com/blog/2019/07/20/how-to-server-side-render-web-components/ https://nextjs.org/docs/getting-started/react-essentials#third-party-packages
Validations
- [X] Follow our Code of Conduct
- [X] Read the docs.
- [X] Check that there isn't already an issue that request the same feature to avoid creating a duplicate.
Would you like to open a PR for this feature?
- [ ] I'm willing to open a PR
up
Any updates on this? We are updating to react 18, and this is causing us to have to force any elements that have a react swiper to be rendered client side. If we can, we would love to be able to render them on the server. There is no data in them that requires loading on the client.
same here, let's go HEROS!
https://www.youtube.com/watch?v=imhdh4xCh7I
followed it and it worked just fine 🚀
"use client";
import Image from "next/image";
import { Swiper, SwiperSlide } from "swiper/react";
import { Navigation, Pagination } from "swiper/modules";
import "swiper/css";
import "swiper/css/navigation";
import "swiper/css/pagination";
import { images } from "@/lib/images";
export default function Page() {
return (
<section className="py-12">
<div className="container">
<Swiper
navigation
pagination={{ type: "bullets", clickable: true }}
modules={[Navigation, Pagination]}
onSwiper={(swiper) => console.log(swiper)}
className="h-[500px] w-full rounded-lg"
>
{images.map((image) => (
<SwiperSlide key={image.alt}>
<div className="flex h-full w-full items-center justify-center">
<Image
src={image.src}
alt={image.alt}
className="block h-full w-full object-cover"
/>
</div>
</SwiperSlide>
))}
</Swiper>
</div>
</section>
);
}
// @/lib/images.ts
import first from "@/public/slides/first.jpg";
import second from "@/public/slides/second.jpg";
import third from "@/public/slides/third.jpg";
import fourth from "@/public/slides/fourth.jpg";
export const images = [
{ src: first, alt: "first" },
{ src: second, alt: "second" },
{ src: third, alt: "third" },
{ src: fourth, alt: "fourth" },
];
Up
@felipe-muner swiper-react will be deprecated. This is about swiper-element
Up 👍
any update on this?
up
For anyone trying to use swiper in react, suggest to migrate to embla that's used under the hood in shadcn https://github.com/davidjerleke/embla-carousel
up
up