2025-04-13 Web Development, Design

A Random Hero Title Font Selector Component in Next.js

By O. Wolfson

CS 5uper
OWolf

I want a hero title that uses a different font every time a website visitor loads the page. A simple way to add some variety and personality to a design. To achieve this, I created a react component that randomly picks a typeface from a list of custom fonts.


Big thanks to Cedilla Studio for letting me use their fonts for this. Their work brings character and unpredictability in the best way. Cedilla offers unique fonts, Lightroom presets, and custom design services. — Francis Bacon (the philosopher) wrote: “The job of the artist is always to deepen the mystery.” Cedilla Studio is deepening the mystery for us. Check out their work at cedilla.studio and follow the founder on Instagram at @type.otf.


How The Component Works

I am working in React / Next.js, so the explanation will be based on that.

  1. Fonts: We added several custom fonts in the fonts/ folder and imported them using Next.js’s localFont utility.
  2. Font Selection: The component uses useMemo to pick one font at random when the component is first rendered.
  3. Rendering: That font is applied to the <h1> element to display the hero title in a bold, oversized style.

It’s lightweight, consistent, and makes each page load feel a little different.


File Tree

bash
random-font-hero
├── fonts
│   ├── CS-5uper.otf
│   ├── CS-Defiant2.woff2
│   ├── CS-Endless.woff2
│   ├── CS-Glare.otf
│   └── CS-Noire-Black.otf
├── fonts.ts
└── random-font-hero.tsx

fonts.ts

ts
import localFont from "next/font/local";

export const csDefiant = localFont({
  src: "./fonts/CS-Defiant2.woff2",
  variable: "--font-cs-defiant",
  display: "swap",
});

export const csEndless = localFont({
  src: "./fonts/CS-Endless.woff2",
  variable: "--font-cs-endless",
  display: "swap",
});

export const cs5uper = localFont({
  src: "./fonts/CS-5uper.otf",
  variable: "--font-cs-5uper",
  display: "swap",
});

export const csGlare = localFont({
  src: "./fonts/CS-Glare.otf",
  variable: "--font-cs-glare",
  display: "swap",
});

export const fonts = [csDefiant, csEndless, cs5uper, csGlare];

random-font-hero.tsx

tsx
"use client";

import { useMemo } from "react";
import { fonts } from "./fonts";

interface HeroTitleProps {
  children: React.ReactNode;
  className?: string;
}

export default function HeroTitle({
  children,
  className = "",
}: HeroTitleProps) {
  const font = useMemo(() => {
    const randomIndex = Math.floor(Math.random() * fonts.length);
    return fonts[randomIndex];
  }, []);

  return (
    <h1
      className={`${font.className} ${className} sm:text-[22rem] text-9xl font-bold text-center`}
    >
      {children}
    </h1>
  );
}