Production-ready, lightweight fully customizable React carousel component that rocks supports multiple items and SSR(Server-side rendering).



Big thanks to BrowserStack for letting the maintainers use their service to debug browser issues.
Bundle-size. 2.5kB
Documentation is here.
Demo for the SSR https://react-multi-carousel.now.sh/
Try to disable JavaScript to test if it renders on the server-side.
Codes for SSR at github.
Codes for the documentation at github.
$ npm install react-multi-carousel --save
import Carousel from 'react-multi-carousel';
import 'react-multi-carousel/lib/styles.css';
Codes for SSR at github.
Here is a lighter version of the library for detecting the user's device type alternative
You can choose to only bundle it on the server-side.
import Carousel from "react-multi-carousel";
import "react-multi-carousel/lib/styles.css";
const responsive = {
superLargeDesktop: {
// the naming can be any, depends on you.
breakpoint: { max: 4000, min: 3000 },
items: 5,
},
desktop: {
breakpoint: { max: 3000, min: 1024 },
items: 3,
},
tablet: {
breakpoint: { max: 1024, min: 464 },
items: 2,
},
mobile: {
breakpoint: { max: 464, min: 0 },
items: 1,
},
};
<Carousel responsive={responsive}>
Item 1
Item 2
Item 3
Item 4
</Carousel>;
import Carousel from "react-multi-carousel";
import "react-multi-carousel/lib/styles.css";
const responsive = {
desktop: {
breakpoint: { max: 3000, min: 1024 },
items: 3,
slidesToSlide: 3, // optional, default to 1.
},
tablet: {
breakpoint: { max: 1024, min: 464 },
items: 2,
slidesToSlide: 2, // optional, default to 1.
},
mobile: {
breakpoint: { max: 464, min: 0 },
items: 1,
slidesToSlide: 1, // optional, default to 1.
},
};
<Carousel
swipeable={false}
draggable={false}
showDots={true}
responsive={responsive}
ssr={true} // means to render carousel on server-side.
infinite={true}
autoPlay={this.props.deviceType !== "mobile" ? true : false}
autoPlaySpeed={1000}
keyBoardControl={true}
customTransition="all .5"
transitionDuration={500}
containerClass="carousel-container"
removeArrowOnDeviceType={["tablet", "mobile"]}
deviceType={this.props.deviceType}
dotListClass="custom-dot-list-style"
itemClass="carousel-item-padding-40-px"
>
Item 1
Item 2
Item 3
Item 4
</Carousel>;
You can pass your own custom arrows to make it the way you want, the same for the position. For example, add media query for the arrows to go under when on smaller screens.
You custom arrows will receive a list of props/state that's passed back by the carousel such as the currentSide, is dragging or swiping in progress.
const CustomRightArrow = ({ onClick, ...rest }) => {
const {
onMove,
carouselState: { currentSlide, deviceType },
} = rest;
// onMove means if dragging or swiping in progress.
return <button onClick={() => onClick()} />;
};
<Carousel customRightArrow={<CustomRightArrow />} />;
This is very useful if you don't want the dots, or arrows and you want to fully customize the control functionality and styling yourself.
const ButtonGroup = ({ next, previous, goToSlide ...rest }) => {
const { carouselState: { currentSlide } } = rest;
return (
// remember to give it position:absolute
<ButtonOne className={currentSlide === 0 : 'disable' : ''} onClick={() => previous()} />
<ButtonTwo onClick={() => next()} />
<ButtonThree onClick={() => goToSlide(currentSlide + 1)}> Go to any slide </ButtonThree>
);
};
<Carousel arrows={false} customButtonGroup={<ButtonGroup />}>
<ItemOne>
<ItemTwo>
</Carousel>
Passing this props would render the button group outside of the Carousel container. This is done using React.fragment
<Carousel arrows={false} renderButtonGroupOutside={true} customButtonGroup={<ButtonGroup />}>
<ItemOne>
<ItemTwo>
</Carousel>
You can pass your own custom dots to replace the default one.
Custom dots can also be a copy or an image of your carousel item. See example in this one
The codes for this example
You custom dots will receive a list of props/state that's passed back by the carousel such as the currentSide, is dragging or swiping in progress.
const CustomDot = ({ onClick, ...rest }) => {
const { onMove, index, active, carouselState: { currentSlide, deviceType } } = rest;
const carouselItems = [CarouselItem1, CaourselItem2, CarouselItem3];
// onMove means if dragging or swiping in progress.
// active is provided by this lib for checking if the item is active or not.
return (
<button className={active ? 'active' : 'inactive'} onClick={() => onClick()}>
{React.Children.toArray(carouselItems)[index]}
</button>
)
}
<Carousel showDots customDot={<CustomDot />}>
{carouselItems}
</Carousel>
Passing this props would render the dots outside of the Carousel container. This is done using React.fragment
<Carousel arrows={false} showDots={true} renderDotsOutside={renderButtonGroupOutside}>
<ItemOne>
<ItemTwo>
</Carousel>
Shows the next items partially, this is very useful if you want to indicate to the users that this carousel component is swipable, has more items behind it.
This is different from the "centerMode" prop, as it only shows the next items. For the centerMode, it shows both.
const responsive = {
desktop: {
breakpoint: { max: 3000, min: 1024 },
items: 3,
partialVisibilityGutter: 40 // this is needed to tell the amount of px that should be visible.
},
tablet: {
breakpoint: { max: 1024, min: 464 },
items: 2,
partialVisibilityGutter: 30 // this is needed to tell the amount of px that should be visible.
},
mobile: {
breakpoint: { max: 464, min: 0 },
items: 1,
partialVisibilityGutter: 30 // this is needed to tell the amount of px that should be visible.
}
}
<Carousel partialVisible={true} responsive={responsive}>
<ItemOne />
<ItemTwo />
</Carousel>
Shows the next items and previous items partially.
<Carousel centerMode={true} />
This is a callback function that is invoked each time when there has been a sliding.
<Carousel
afterChange={(previousSlide, { currentSlide, onMove }) => {
doSpeicalThing();
}}
/>
This is a callback function that is invoked each time before a sliding.
<Carousel
beforeChange={(nextSlide, { currentSlide, onMove }) => {
doSpeicalThing();
}}
/>
They are very useful in the following cases:
<Carousel
beforeChange={() => this.setState({ isMoving: true })}
afterChange={() => this.setState({ isMoving: false })}
>
<a
onClick={e => {
if (this.state.isMoving) {
e.preventDefault();
}
}}
href="https://w3js.com"
>
Click me
</a>
</Carousel>
<Carousel beforeChange={nextSlide => this.setState({ nextSlide: nextSlide })}>
Initial slide
{
if (this.state.nextSlide === 1) {
doVerySpecialThing();
}
}}
>
Second slide
</Carousel>
When calling the goToSlide function on a Carousel the callbacks will be run by default. You can skip all or individul callbacks by passing a second parameter to goToSlide.
this.Carousel.goToSlide(1, true); // Skips both beforeChange and afterChange
this.Carousel.goToSlide(1, { skipBeforeChange: true }); // Skips only beforeChange
this.Carousel.goToSlide(1, { skipAfterChange: true }); // Skips only afterChange
Go to slide on click and make the slide a current slide.
<Carousel focusOnSelect={true} />
<Carousel ref={(el) => (this.Carousel = el)} arrows={false} responsive={responsive}>
<ItemOne />
<ItemTwo />
</Carousel>
<button onClick={() => {
const nextSlide = this.Carousel.state.currentSlide + 1;
// this.Carousel.next()
// this.Carousel.goToSlide(nextSlide)
}}>Click me</button>
This is very useful when you are fully customizing the control functionality by yourself like this one
For example if you give to your carousel item padding left and padding right 20px. And you have 5 items in total, you might want to do the following:
<Carousel ref={el => (this.Carousel = el)} additionalTransfrom={-20 * 5} /> // it needs to be a negative number
| Name | Type | Default | Description
$ claude mcp add react-multi-carousel \
-- python -m otcore.mcp_server <graph>