Skip to main content

Server-Side Rendering (SSR)

Flicking works with SSR frameworks like Next.js and Nuxt. However, since Flicking calculates panel positions based on DOM element sizes, panels may shift after hydration. This guide covers how to prevent that.

The Problem

Flicking needs to measure the actual size of panel elements to position them correctly. During SSR, these measurements aren't available, so panels may appear in the wrong position until Flicking initializes on the client side.

This is especially noticeable when:

  • Using align: "center" (the default) or other non-"prev" alignments
  • Panels have different sizes

Solution 1: firstPanelSize

If you know the size of the first panel, provide it via the firstPanelSize option. Flicking will use this to calculate the correct camera position before initialization.

<div id="flicking" class="flicking-viewport">
<div class="flicking-camera">
<div class="panel">1</div>
<div class="panel">2</div>
<div class="panel">3</div>
</div>
</div>
import Flicking from "@egjs/flicking";

const flicking = new Flicking("#flicking", {
firstPanelSize: "200px"
});

You can use any CSS length value: "200px", "50%", etc.

caution

firstPanelSize does not work well with the circular option, because circular mode clones panels and their positions depend on actual DOM measurements.

Solution 2: hideBeforeInit

If you don't know the panel size in advance, you can hide the panels until Flicking finishes initialization. This prevents layout shifts by showing nothing until the correct positions are calculated.

import Flicking from "@egjs/flicking";

const flicking = new Flicking("#flicking", {
hideBeforeInit: true
});

When hideBeforeInit is enabled, Flicking adds the flicking-hidden CSS class to the viewport, which sets visibility: hidden on all panel elements. The class is automatically removed once Flicking is ready.

tip

You can combine both options. Use firstPanelSize for correct positioning and hideBeforeInit as a fallback for cases where the size estimate is inaccurate.

Which Option Should I Choose?

firstPanelSizehideBeforeInit
BehaviorPositions panels using estimated sizeHides panels until ready
Visual resultPanels visible immediately, minimal shiftEmpty space until initialization
Best forKnown, fixed panel sizesDynamic or unknown panel sizes
Works with circularNoYes

Reactive API and SSR

If you're using the Reactive API to build UI components like pagination or navigation, you can provide initial values to prevent hydration mismatches:

const { currentPanelIndex, totalPanelCount } = useFlickingReactiveAPI(flickingRef, {
defaultIndex: 0,
totalPanelCount: 10
});

See the Reactive API guide for details.