05Slide Transition

Slide Transition

GSAPMobileSequentialParallax

Classic horizontal page sliding effect with parallax on content. Old page slides out to the left, new one slides in from the right. Ideal for wizard flows, onboarding, and mobile apps.

Quick Start

  • 📦npm install next-transition-router gsap
  • 🔧Slide wrapper + content with different speeds for parallax
  • 📱overflow: hidden on parent prevents scrollbar
  • ✨Content moves faster than container for depth effect

Installation

Terminal
1npm install next-transition-router gsap

Provider Setup

app/providers.tsx
1'use client'
2
3import { useRef } from 'react'
4import { TransitionRouter } from 'next-transition-router'
5import gsap from 'gsap'
6
7export default function SlideProvider({ children }: { children: React.ReactNode }) {
8 const wrapperRef = useRef<HTMLDivElement>(null)
9
10 return (
11 <TransitionRouter
12 auto
13 leave={(next) => {
14 const tl = gsap.timeline({ onComplete: next })
15 const wrapper = wrapperRef.current
16 const content = wrapper?.querySelectorAll('h1, p, .btn, .demo-badge')
17
18 // Content slides faster (parallax effect)
19 tl.to(content, {
20 x: -80,
21 opacity: 0,
22 stagger: 0.03,
23 duration: 0.4,
24 ease: 'power3.in',
25 })
26
27 // Wrapper slides out
28 tl.to(wrapper, {
29 x: '-100%',
30 duration: 0.5,
31 ease: 'power4.inOut',
32 }, '-=0.25')
33 }}
34 enter={(next) => {
35 const tl = gsap.timeline({ onComplete: next })
36 const wrapper = wrapperRef.current
37 const content = wrapper?.querySelectorAll('h1, p, .btn, .demo-badge')
38
39 gsap.set(wrapper, { x: '100%' })
40 gsap.set(content, { x: 60, opacity: 0 })
41
42 tl.to(wrapper, {
43 x: '0%',
44 duration: 0.5,
45 ease: 'power4.out',
46 })
47
48 tl.to(content, {
49 x: 0,
50 opacity: 1,
51 stagger: 0.05,
52 duration: 0.45,
53 ease: 'power3.out',
54 }, '-=0.3')
55 }}
56 >
57 <div ref={wrapperRef} style={{ width: '100%' }}>
58 {children}
59 </div>
60 </TransitionRouter>
61 )
62}

Layout with overflow hidden

app/layout.tsx
1import SlideProvider from './providers'
2
3export default function SlideLayout({ children }: { children: React.ReactNode }) {
4 return (
5 <div style={{ overflow: 'hidden', width: '100%' }}>
6 <SlideProvider>{children}</SlideProvider>
7 </div>
8 )
9}