Yi
5 min readMar 20, 2019

--

Building a React Carousel component that rocks with Server Side Rendering Support — Part 1

react-multi-carousel

With this article I am going to show you how you can create your own Carousel component using React that supports multiple items and server-side rendering with the bare minimum amount of codes.

This is part one of the series “Building a react Carousel component with Server Side Rendering Support” that was originally published at w3js.

Part two can be found here:

https://medium.com/w3js/building-a-react-carousel-component-that-rocks-with-server-side-rendering-support-part-2-fe89ce27e113

If you prefer to jump right to the code, i have made two versions of the Carousel, first version is the one we will be building in this tutorial with basic usage and the bare minimal amount of code that’s easier for you to understand and beginner friendly. For the second version, it is made as a npm package which is an improved version of the first one with more advanced usage.

The source code for the Carousel we are building is here on Github. The Carousel npm package with more advanced usage.

Content:

  • Why build a Carousel component?
  • Common technical approach.
  • The Carousel we are building.
  • Technical approach we are going to use.

Why build a Carousel component?

  1. The problem with most of the Carousel components out there nowadays are either built with Jquery(84.6kb of bundle size) or only supports client-end rendering. It means our content will be completely empty for the initial load and this will have an impact on the performance and user-experience as well as SEO. (I will explain why in the following section).
  2. Server-side rendering has already been a leading force in building front-end applications, especially with the rise of frameworks like Nextjs, there’s often a need to implement a Carousel component to show case for instance a list of products or a list of articles on your website while keeping the performance and SEO up.

Common technical approach.

One of the most common ways to building a Carousel component is to calculate the entire width of the Carousel component and divided by the amount of items you want to show will eventually be the average width of item inside the Carousel. After all the items are rendered nicely, the navigation are usually done by changing the “transform” property of the Carousel container with either “translateX” or “translate3d” with some math calculations as the following code snippets:

const itemsToShow = 4;
const containerWidth = document.getElementById("#container").offsetWidth;
const itemWidth = containerWidth / 4;
<Carousel>
<item1 style="width=itemWidth" />
<item2 style="width=itemWidth" />
<item3 style="width=itemWidth" />
</Carousel>

The problem with this approach is that we don’t have access to the actual window object and the width and height of the Carousel component on server-side. So what’s gonna happen is that our user will see complete blank content at the beginning, and after some amount of time our browser finished downloading and executing the JavaScript codes to finally gain access to the dom, it will trigger a re-rendering and fix up our Carousel items. The following diagram will be a clearer illustration:

Flow of the Carousel rendering in the server-side rendering

The Carousel we are building:

Features:

  1. Supports showing multiple items at the same time.
  2. Supports sliding items to items.
  3. Support infinite sliding.
  4. Support server side rendering.

Technical approach:

Here is the approach that we will be using, don’t worry if you don’t completely understand, but you will learn about it more once we get to the implementation step by step later.

  1. Pre-define the numbers of items we are showing at the same time at each break point, an example:
const breakpoints = {
desktop: {
breakpoint: { max: 3000, min: 1024 },
items: 3 // show 3 items at screen size between 3000px and 1024px
},
tablet: {
breakpoint: { max: 1024, min: 464 },
items: 2
},
mobile: {
breakpoint: { max: 464, min: 0 },
items: 1
}
}

2. On the server-side we will be detecting the user’s device type based on the user agent which comes with the request header which is a string.

function getDeviceTypeFromUserAgent(userAgent) {
// code for detecting the device based on userAgent, you can use a library for this.
// return "mobile" / 'tablet' / 'desktop'
}
function detectDevice(req) {
let userAgent;
if (req) {
userAgent = req.headers["user-agent"];
} else {
userAgent = navigator.userAgent;
}
return getDeviceTypeFromUserAgent(userAgent)
}

3. Do a comparison between the user’s device type and our pre-defined break-point to determine the numbers of items we are showing at the same time.

  1. Divide the numbers of items by 100%, and ultimately setting the average of it to flex-basis to each item. For example, if we have decided to show 3 items after knowing the type of the user’s device, then it means each item should take up 33% of the available space inside the container, by setting the flex-basis does exactly that. See code snippet below.
  2. After the initial load and when our browser has finished downloading our JavaScript code, we will trigger a re-rendering and switch to the most common approach that was mentioned at the beginning of this article which is to access our dom to get the total width of the container that’s housing our carousel items.
const itemsToShowWhenOnServerSide = 3;
<CarouselItem style="flex-basis=33%" />

--

--