Each selling point is a colourful, chunky 3D block. The blocks fall from above, bounce into a deliberate stacked composition, and respond to hover and click — your product benefits, rendered as playful building blocks.
import FeatureBlocks from '@crazygl/hero-feature-blocks-playground';
export default function Hero() {
return (
<FeatureBlocks
heading="Built to stack."
block1Label="FAST" block1Emoji="⚡"
block2Label="SECURE" block2Emoji="🛡️"
onBlock1Click={(e) => console.log('clicked FAST', e)}
onBlock2Click="/features/security"
/>
);
}Each onBlock{1..6}Click accepts EITHER a string URL (the customizer-facing form, navigates via window.location.href) OR a function called with the PointerEvent. One prop, type-detected at runtime.
heading / subheading, or two-columns / custom via contentType.blockCount (1–6), gravityStrength (0 skips the fall), hoverLift, pointerParallax, plus groupOffsetX/Y and groupScale.block{n}Label, block{n}Color, block{n}Emoji, onBlock{n}Click.transparentBackground, or bgTop / bgBottom for the warm-cream gradient.headingFontFamily.npm install @crazygl/hero-feature-blocks-playgroundThe component takes the same props you see in the live customizer on the right — every default ships poster-quality.
import FeatureBlocksPlayground from '@crazygl/hero-feature-blocks-playground';
export default function Landing() {
return (
<FeatureBlocksPlayground />
);
}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 FeatureBlocksPlayground from '@crazygl/hero-feature-blocks-playground';
export default function Page() {
return (
<section>
<FeatureBlocksPlayground
heading="Say hi."
subheading="Your new hero."
/>
<article>
<h2>Welcome</h2>
<p>Your content keeps its own voice below the hero.</p>
</article>
</section>
);
}