A long paragraph that reveals as the viewer scrolls — word-by-word, letter-by-letter, or line-by-line — with a soft ghost copy underneath that hints at the next words just before they arrive.
import UltimateScrollText from '@crazygl/hero-ultimate-scroll-text';
export default function Page() {
return (
<UltimateScrollText
text={'We build calm software for focused teams.\nNo noise. No bloat. Just the work.'}
unit="Words"
scrollStart={15}
scrollEnd={70}
ghostEnabled
ctaLabel="Read the manifesto"
onCTAClick="/manifesto"
/>
);
}When used in React you can pass
onCTAClickeither a URL string or a function callback.
text, ctaLabel, onCTAClick (url string or function), unit (Words / Letters / Lines).scrollStart, scrollEnd (% of progress the reveal spans), autoplaySeconds (time-based sweep when the page doesn't scroll).ghostEnabled, ghostOpacity, ghostColor.textColor, textAlign, fontSize, lineHeight, letterSpacing, maxWidth, wordGap, headingFontFamily, headingFontWeight.accentColor, accentStrength, vignetteStrength, transparentBackground, bgColor.npm install @crazygl/hero-ultimate-scroll-textThe component takes the same props you see in the live customizer on the right — every default ships poster-quality.
import UltimateScrollText from '@crazygl/hero-ultimate-scroll-text';
export default function Landing() {
return (
<UltimateScrollText />
);
}The wrapper renders static HTML on the server and only initialises the canvas after hydration, so search engines see your copy.
// app/page.tsx — works in SSR-first frameworks (Next, Remix, Astro, etc.)
'use client';
import UltimateScrollText from '@crazygl/hero-ultimate-scroll-text';
export default function Page() {
return (
<section>
<UltimateScrollText
heading="Say hi."
subheading="Your new hero."
/>
<article>
<h2>Welcome</h2>
<p>Your content keeps its own voice below the hero.</p>
</article>
</section>
);
}