Skip to content
Template Empire / components

Search components

10 results

Browse components

Stats Hero

A free animated hero section where the stats are the motion.

  • Automated axe check
  • Reduced-motion tested
  • SSR build verified
  • GSAP
  • 2 runtime packages

Stats Hero is a free animated hero section for Next.js and React that pairs a calm typographic headline with a row of live counters. It is built with GSAP and ScrollTrigger, styled with Tailwind, and composes the Count Up component through a registry dependency, so each stat counts up from zero the moment it scrolls into view.

You pass a title, an optional subtitle, one call to action and up to four stats, and the section handles the rest: the headline, subtitle, CTA and stat row rise in sequence as whole blocks, then the counters settle on their real numbers. The final formatted values are rendered in the server HTML, so crawlers and reduced-motion users always read the finished figures, and tabular numerals keep the layout perfectly still while the counts run.

The numbers behind every launch

Stats Hero keeps the first screen calm and typographic, then lets the figures do the moving: each metric counts up from zero the moment it scrolls into view.

Teams shipping weekly

Uptime last quarter

Processed each year

Install

Add the @te registry to your components.json once:

{
  "registries": {
    "@te": "https://templateempire.io/r/{name}.json"
  }
}

Then install the component:

npx shadcn@latest add @te/hero-stats

Usage

import { HeroStats } from "@/components/hero-stats";

export default function Page() {
  return (
    <HeroStats
      title="The numbers behind every launch"
      subtitle="A calm typographic hero where the stats do the moving."
      cta={{ label: "Get started", href: "/signup" }}
      stats={[
        { value: 42000, suffix: "+", label: "Teams shipping weekly" },
        {
          value: 99.98,
          suffix: "%",
          decimals: 2,
          label: "Uptime last quarter",
        },
        {
          value: 1.8,
          prefix: "$",
          suffix: "B",
          decimals: 1,
          label: "Processed each year",
        },
      ]}
    />
  );
}

Props

PropTypeDefaultDescription
titlestringrequiredHeadline copy, rendered as the section's single h1.
subtitlestringundefinedSupporting copy rendered below the headline.
cta{ label: string; href: string }requiredPrimary call to action, rendered as a real anchor.
stats{ value: number; label: string; prefix?: string; suffix?: string; decimals?: number }[]requiredOne to four stats rendered with Count Up counters.
classNamestringundefinedAdditional classes merged onto the section root.

Customisation

Stats Hero declares no tokens of its own; it is a calm typographic section that consumes the global semantic tokens directly. Override --foreground for the headline, stat values and the inverted call to action, --muted for the supporting copy and stat labels, and --border for the rule above the stat row, from :root or any ancestor of the hero, to retheme the whole section without touching the code:

:root {
  --foreground: var(--color-neutral-50);
  --muted: oklch(from var(--color-neutral-50) l c h / 0.7);
}

Frequently asked questions

Is Stats Hero free for commercial use?
Yes. Stats Hero is MIT licensed, so you can use it in personal and commercial projects without attribution.
Does Stats Hero affect performance or accessibility?
The entrance animates transforms and opacity only, inside space the layout has already reserved, and the counters use tabular numerals so their width never changes while counting, which keeps layout shift at zero. The final numbers are rendered in the server HTML and each counter carries its finished value as an accessible name, so screen readers never hear intermediate counts. The call to action is a real anchor with a visible focus ring, and with reduced motion enabled the full section renders immediately with the final figures in place.
How do I format the numbers in the stat row?
Each stat accepts prefix, suffix and decimals, so you can render values like $1.8B or 99.98% directly. Grouping and decimal separators come from a fixed en-US Intl.NumberFormat inside the Count Up component, which keeps server and client output identical.

Related components

Want the full page this belongs to?Template Empire builds complete Next.js templates with this motion system throughout. Browse the paid templates that pair with these free components.Explore Template Empire templates