Understanding Hydration Mismatches with Lenis Smooth Scroll in Next.js 14
Integrating lenis or smooth scroll libraries in Next.js 14 App Router applications frequently triggers React hydration warning errors such as "Text content does not match server-rendered HTML" or layout jitter during initial client navigation. This occurs because Lenis injects dynamic inline styles onto the html and body DOM elements before React completes its client-side hydration phase.
When Server-Side Rendering (SSR) outputs clean static DOM markup without inline scroll style attributes, and Lenis initializes on mount prior to hydration, React detects a DOM property imbalance, resulting in hydration failures and Web Vitals (INP/CLS) score degradation.
Step-by-Step Fix: Building a Safe Client Component Wrapper
To prevent Lenis from mutating DOM attributes prior to React client mounting, encapsulate Lenis inside a dedicated 'use client' provider with double-pass rendering and RequestAnimationFrame lifecycle management.
Optimizing Cumulative Layout Shift (CLS) & Scroll Performance
Ensure that Lenis smooth scroll CSS rules are loaded globally without overriding default touch events on mobile viewports. Overriding touch scroll on mobile devices harms Google Core Web Vitals performance scores.
- Use
smoothWheel: trueandsyncTouch: false: Keep native mobile touch scrolling untouched. - Prevent Body Height Shifts: Add
html.lenis, html.lenis body { height: auto; }to your global CSS. - Disable Lenis on Modals: Use
data-lenis-preventon scrollable modal overlays to prevent scroll locks.
