The whole background is a grid of ASCII glyphs that, from afar, reads as a soft drifting nebula — dense glyphs where the cloud is thick, sparse where it thins. The pointer locally reveals hidden structure: nearby glyphs grow larger, rotate slightly, and switch to denser symbols.
import AsciiNebula from '@crazygl/hero-ascii-nebula';
export default function Hero() {
return (
<AsciiNebula
heading="Hidden structure."
densityRamp=" .:+*#@"
glyphColor="#c9c2ff"
/>
);
}heading + subheading, two-column, or a custom node.densityRamp (glyphs thin → dense) or customChars to swap in brand letters; cellSize (8–28px), cloudScale, driftSpeed, contrast.glyphColor (pale violet by default) and backgroundColor (near-black space).revealRadius, revealStrength, glyphRotate tune how the cursor condenses, enlarges, and swirls nearby glyphs.transparent to drop the background fill.npm install @crazygl/hero-ascii-nebulaThe component takes the same props you see in the live customizer on the right — every default ships poster-quality.
import ASCIINebula from '@crazygl/hero-ascii-nebula';
export default function Landing() {
return (
<ASCIINebula />
);
}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 ASCIINebula from '@crazygl/hero-ascii-nebula';
export default function Page() {
return (
<section>
<ASCIINebula
heading="Say hi."
subheading="Your new hero."
/>
<article>
<h2>Welcome</h2>
<p>Your content keeps its own voice below the hero.</p>
</article>
</section>
);
}