Jarallax can be seamlessly integrated into React and Next.js applications using custom wrapper components. This guide shows you how to build reusable components and handle server-side rendering.
Installation
First, install Jarallax in your React or Next.js project:
React Component Setup
Create reusable React components for Jarallax functionality:
Create the Jarallax Component
Build a wrapper component that manages the parallax lifecycle: import React , { useRef , useEffect } from 'react' ;
import { jarallax , jarallaxVideo } from 'jarallax' ;
import 'jarallax/dist/jarallax.min.css' ;
// Optional video extension
jarallaxVideo ();
export default function Jarallax ({ className = '' , children , ... props }) {
const $el = useRef ();
// Init Jarallax
useEffect (() => {
if ( $el . current ) {
jarallax ( $el . current , props );
}
// Destroy Jarallax on cleanup
return function destroy () {
if ( $el . current ) {
jarallax ( $el . current , 'destroy' );
}
};
}, []);
// Update options when props change
useEffect (() => {
if ( $el . current ) {
jarallax ( $el . current , 'destroy' );
jarallax ( $el . current , props );
}
}, [ props ]);
return (
< div ref = { $el } className = { `jarallax ${ className } ` } >
{ children }
</ div >
);
}
This component properly handles initialization, cleanup, and prop updates to prevent memory leaks.
Create the Image Component
Create a simple component for parallax images: components/JarallaxImage.js
export default function JarallaxImage ({ className = '' , ... props }) {
return < img className = { `jarallax-img ${ className } ` } { ... props } /> ;
}
Use in Your Application
Import and use the components in your React app: import Jarallax from './components/Jarallax' ;
import JarallaxImage from './components/JarallaxImage' ;
function App () {
return (
< div >
< Jarallax speed = { 0.2 } >
< JarallaxImage
src = "https://jarallax.nkdev.info/images/image1.jpg"
alt = "Parallax background"
/>
< div className = "content" >
< h1 > Your Content Here </ h1 >
</ div >
</ Jarallax >
</ div >
);
}
Next.js Integration
Next.js requires special handling due to server-side rendering (SSR). Jarallax needs to run only on the client side.
Basic Next.js Setup
Here’s how to integrate Jarallax in a Next.js application:
import Head from 'next/head' ;
import dynamic from 'next/dynamic' ;
// Disable SSR for Jarallax component
const Jarallax = dynamic (() => import ( '../components/Jarallax' ), { ssr: false });
import JarallaxImage from '../components/JarallaxImage' ;
export default function Index () {
return (
<>
< Head >
< title > Next.js Parallax Example </ title >
</ Head >
< div className = "section" >
< h1 > Next.js Example </ h1 >
</ div >
< Jarallax speed = { 0.2 } >
< JarallaxImage src = "https://jarallax.nkdev.info/images/image1.jpg" alt = "" />
</ Jarallax >
< Jarallax speed = { 0.2 } videoSrc = "https://youtu.be/mru3Q5m4lkY" />
< div className = "section" />
</>
);
}
Always use dynamic import with { ssr: false } for the Jarallax component to prevent server-side rendering issues.
App Router Setup (Next.js 13+)
For Next.js App Router, mark your component as a Client Component:
'use client' ;
import React , { useRef , useEffect } from 'react' ;
import { jarallax , jarallaxVideo } from 'jarallax' ;
import 'jarallax/dist/jarallax.min.css' ;
jarallaxVideo ();
export default function Jarallax ({ className = '' , children , ... props }) {
const $el = useRef ();
useEffect (() => {
if ( $el . current ) {
jarallax ( $el . current , props );
}
return function destroy () {
if ( $el . current ) {
jarallax ( $el . current , 'destroy' );
}
};
}, []);
useEffect (() => {
if ( $el . current ) {
jarallax ( $el . current , 'destroy' );
jarallax ( $el . current , props );
}
}, [ props ]);
return (
< div ref = { $el } className = { `jarallax ${ className } ` } >
{ children }
</ div >
);
}
Advanced Next.js Example
Here’s a complete example with dynamic state management and interactive controls:
import React , { useState } from 'react' ;
import Head from 'next/head' ;
import dynamic from 'next/dynamic' ;
const Jarallax = dynamic (() => import ( '../components/Jarallax' ), { ssr: false });
import JarallaxImage from '../components/JarallaxImage' ;
export default function Index () {
const [ blocks , updateBlocks ] = useState ([
{
uid: 1 ,
options: {
type: 'scroll' ,
src: 'https://source.unsplash.com/random/1280x720' ,
speed: 0.6 ,
},
},
]);
function addNewBlock () {
const randomImage = `https://source.unsplash.com/random/1280x72 ${ blocks . length % 10 } ` ;
let uid = 1 ;
if ( blocks [ blocks . length - 1 ]) {
uid = blocks [ blocks . length - 1 ]. uid + 1 ;
}
updateBlocks ([
... blocks ,
{
uid: uid ,
options: {
type: 'scroll' ,
src: randomImage ,
speed: 0.6 ,
},
},
]);
}
function removeBlock ( id ) {
updateBlocks (
blocks . filter (( data , i ) => {
return id !== i ;
})
);
}
function changeBlockOptions ( id , newOptions ) {
updateBlocks (
blocks . map (( data , i ) => {
if ( id === i ) {
return {
... data ,
options: {
... data . options ,
... newOptions ,
},
};
}
return data ;
})
);
}
return (
<>
< Head >
< title > Next.js Advanced Example </ title >
</ Head >
< div className = "section" >
< h1 > Next.js Advanced Example </ h1 >
</ div >
< div className = "wrapper" >
< button className = "btn btn-primary" onClick = { addNewBlock } >
+ Add New Parallaxed Block
</ button >
< br />
< br />
{ blocks . map (({ uid , options }, i ) => (
< div className = "jarallax-wrap" key = { uid } >
< Jarallax type = { options . type } speed = { options . speed } >
< JarallaxImage src = { options . src } alt = "" />
</ Jarallax >
< div className = "jarallax-controls" >
< div className = "form-group" >
< label > Parallax Type </ label >
< select
className = "form-control"
value = { options . type }
onChange = { ( e ) => {
changeBlockOptions ( i , {
type: e . target . value ,
});
} }
>
< option value = "scroll" > Scroll </ option >
< option value = "scale" > Scale </ option >
< option value = "opacity" > Opacity </ option >
< option value = "scroll-opacity" > Scroll Opacity </ option >
< option value = "scale-opacity" > Scale Opacity </ option >
</ select >
< label > Parallax Speed </ label >
< input
className = "form-control"
type = "number"
min = "-1"
max = "2"
step = "0.1"
value = { options . speed }
onChange = { ( e ) => {
changeBlockOptions ( i , {
speed: e . target . value ,
});
} }
/>
< button
className = "btn btn-remove"
onClick = { () => {
removeBlock ( i );
} }
>
Remove Block
</ button >
</ div >
</ div >
</ div >
)) }
</ div >
</>
);
}
This advanced example demonstrates how to dynamically add, remove, and update parallax blocks with different configurations in real-time.
Common Props
The Jarallax component accepts all standard Jarallax options as props:
< Jarallax
// Parallax type
type = "scroll" // scroll, scale, opacity, scroll-opacity, scale-opacity
// Parallax speed
speed = { 0.5 } // -1.0 to 2.0
// Image options
imgSrc = "path/to/image.jpg"
imgSize = "cover"
imgPosition = "50% 50%"
// Video options
videoSrc = "https://www.youtube.com/watch?v=ab0TSkLe-E0"
videoStartTime = { 0 }
videoEndTime = { 0 }
videoLoop = { true }
// z-index
zIndex = { - 100 }
// Disable on mobile
disableParallax = { /iPad | iPhone | iPod | Android/ }
// Event handlers
onInit = { () => console . log ( 'Initialized' ) }
onDestroy = { () => console . log ( 'Destroyed' ) }
onScroll = { ( calculations ) => console . log ( calculations ) }
>
< JarallaxImage src = "path/to/image.jpg" alt = "" />
{ /* Your content */ }
</ Jarallax >
Video Backgrounds in React
Enable video backgrounds by ensuring the video extension is initialized:
YouTube Video
Vimeo Video
Self-Hosted Video
< Jarallax
speed = { 0.2 }
videoSrc = "https://www.youtube.com/watch?v=ab0TSkLe-E0"
videoLoop = { true }
>
< div className = "content" >
< h2 > Content over video </ h2 >
</ div >
</ Jarallax >
Styling
Add CSS to control the appearance and layout:
/* Set parallax container height */
.jarallax {
height : 80 vh ;
position : relative ;
}
/* Style content inside parallax */
.jarallax .content {
position : relative ;
z-index : 1 ;
padding : 2 rem ;
color : white ;
text-align : center ;
}
/* Section spacing */
.section {
height : 60 vh ;
display : flex ;
align-items : center ;
justify-content : center ;
}
TypeScript Support
Jarallax includes TypeScript definitions. Create typed components:
import React , { useRef , useEffect , ReactNode } from 'react' ;
import { jarallax , jarallaxVideo , JarallaxOptions } from 'jarallax' ;
import 'jarallax/dist/jarallax.min.css' ;
jarallaxVideo ();
interface JarallaxProps extends JarallaxOptions {
className ?: string ;
children ?: ReactNode ;
}
export default function Jarallax ({
className = '' ,
children ,
... props
} : JarallaxProps ) {
const $el = useRef < HTMLDivElement >( null );
useEffect (() => {
if ( $el . current ) {
jarallax ( $el . current , props );
}
return function destroy () {
if ( $el . current ) {
jarallax ( $el . current , 'destroy' );
}
};
}, []);
useEffect (() => {
if ( $el . current ) {
jarallax ( $el . current , 'destroy' );
jarallax ( $el . current , props );
}
}, [ props ]);
return (
< div ref = { $el } className = { `jarallax ${ className } ` } >
{ children }
</ div >
);
}
Lazy Loading
Conditional Rendering
Memoization
Lazy load parallax components for better initial page load: import dynamic from 'next/dynamic' ;
const Jarallax = dynamic (() => import ( '../components/Jarallax' ), {
ssr: false ,
loading : () => < div className = "loading-placeholder" />
});
Disable parallax on mobile devices to improve performance: import { useState , useEffect } from 'react' ;
export default function MyPage () {
const [ isMobile , setIsMobile ] = useState ( false );
useEffect (() => {
setIsMobile ( /iPad | iPhone | iPod | Android/ . test ( navigator . userAgent ));
}, []);
return (
< Jarallax
speed = { 0.2 }
disableParallax = { isMobile }
>
< JarallaxImage src = "image.jpg" alt = "" />
</ Jarallax >
);
}
Use React.memo to prevent unnecessary re-renders: import React , { memo } from 'react' ;
const Jarallax = memo ( function Jarallax ({ className , children , ... props }) {
// Component implementation
});
export default Jarallax ;
Troubleshooting
Parallax not working in Next.js
Ensure you’re using dynamic import with { ssr: false } for the Jarallax component. The library requires browser APIs that aren’t available during server-side rendering. const Jarallax = dynamic (() => import ( '../components/Jarallax' ), { ssr: false });
Make sure you’re properly handling prop changes in the useEffect hook. The component should destroy and reinitialize Jarallax when props change: useEffect (() => {
if ( $el . current ) {
jarallax ( $el . current , 'destroy' );
jarallax ( $el . current , props );
}
}, [ props ]);
Always clean up Jarallax instances in the useEffect cleanup function: useEffect (() => {
// Initialize
return function destroy () {
if ( $el . current ) {
jarallax ( $el . current , 'destroy' );
}
};
}, []);
Next Steps
Vanilla JavaScript Learn basic Jarallax usage without frameworks
jQuery Integration Use Jarallax with jQuery
API Reference Explore all available methods and options
Configuration Advanced configuration options