Skip to content
goodtabs UI
BrowseBrowse components

Footer mega

A large footer with a lead column, five or six link columns and an oversized wordmark.

npx shadcn@latest add https://ui.goodtabs.co/r/footer-mega.json

With the @goodtabs namespace in components.json: npx shadcn@latest add @goodtabs/footer-mega

Lead line, six link columns, a ghosted wordmark and a legal bar.

Three columns

No lead column; three columns under the wordmark.

Usage

import { FooterMega } from "@/components/footer-mega"

<FooterMega
  lead="Interface parts for teams that ship."
  columns={[{ title: "Product", links: [{ label: "Docs", href: "/docs" }] }]}
  wordmark="Northwind"
  legal="2026 Northwind Ltd."
/>

Props

PropTypeDefaultDescription
leadstringShort pitch in the lead column.
leadSlotReactNodeUnder the lead: a signup form, status pill or button.
columns{ title: string; links: { label: string; href: string }[] }[]Five or six link columns.
wordmarkstringThe oversized word at the bottom.
legalstringLeft of the bottom bar.
bottomReactNodeRight of the bottom bar.

Source

footer-mega/footer-mega.tsx
import * as React from "react";
import { cn } from "@/lib/utils";

export type FooterMegaLink = { label: string; href: string };
export type FooterMegaColumn = { title: string; links: FooterMegaLink[] };

type FooterMegaProps = Omit<React.ComponentProps<"footer">, "children"> & {
  /** Short pitch in the lead column, above the slot. */
  lead?: string;
  /** Under the lead: a signup form, a status pill, a button. */
  leadSlot?: React.ReactNode;
  /** Five or six columns of links. */
  columns: FooterMegaColumn[];
  /** The oversized word at the bottom, usually the product name. */
  wordmark: string;
  /** Left of the bottom bar. */
  legal?: string;
  /** Right of the bottom bar: small links. */
  bottom?: React.ReactNode;
};

/**
 * A big footer for sites with a lot to link to: a lead column, a grid of five or six
 * link columns on hairline rules, and an oversized wordmark above the legal bar.
 */
export function FooterMega({ lead, leadSlot, columns, wordmark, legal, bottom, className, ...props }: FooterMegaProps) {
  const hasLead = Boolean(lead || leadSlot);
  return (
    <footer data-slot="footer-mega" className={cn("w-full overflow-hidden text-sm", className)} {...props}>
      <div
        className={cn(
          "mx-auto grid max-w-6xl gap-10 px-6 py-12 md:px-8",
          hasLead && "lg:grid-cols-[minmax(0,18rem)_minmax(0,1fr)] lg:gap-16",
        )}
      >
        {hasLead && (
          <div className="flex flex-col items-start gap-4">
            {lead && <p className="m-0 text-base font-medium tracking-tight text-balance">{lead}</p>}
            {leadSlot}
          </div>
        )}
        <nav
          aria-label="Footer"
          className="grid grid-cols-2 gap-x-6 gap-y-8 sm:grid-cols-3 lg:grid-cols-[repeat(var(--columns),minmax(0,1fr))]"
          style={{ "--columns": Math.min(columns.length, 6) } as React.CSSProperties}
        >
          {columns.map((column, i) => (
            <div key={i} className="flex flex-col gap-3 border-t pt-3">
              <p className="m-0 font-mono text-xs tracking-wide text-muted-foreground uppercase">{column.title}</p>
              <ul className="m-0 flex list-none flex-col gap-2 p-0">
                {column.links.map((link, j) => (
                  <li key={j}>
                    <a
                      href={link.href}
                      className="rounded-sm text-muted-foreground transition-colors duration-100 ease-out outline-none hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring"
                    >
                      {link.label}
                    </a>
                  </li>
                ))}
              </ul>
            </div>
          ))}
        </nav>
      </div>
      <div aria-hidden className="mx-auto max-w-6xl px-6 md:px-8">
        {/* Decoration, not text: a pseudo-element keeps the 6 percent wordmark out of the document and off the contrast check. */}
        <div
          data-wordmark={wordmark}
          className="pb-4 text-[clamp(3rem,14vw,12rem)] leading-[0.9] font-medium tracking-tighter whitespace-nowrap text-foreground/[0.06] select-none before:content-[attr(data-wordmark)]"
        />
      </div>
      {(legal || bottom) && (
        <div className="border-t">
          <div className="mx-auto flex max-w-6xl flex-col gap-3 px-6 py-5 text-xs text-muted-foreground sm:flex-row sm:items-center sm:justify-between md:px-8">
            {legal && <p className="m-0">{legal}</p>}
            {bottom && <div className="flex flex-wrap items-center gap-4">{bottom}</div>}
          </div>
        </div>
      )}
    </footer>
  );
}

For AI agents

Hand your agent this page, the markdown at /components/footer-mega/prompt.md, or the Copy AI prompt button above.

When to use

  • Sites with five or more groups of links
  • Marketing pages where the footer is a brand moment

When not to use

  • Small sites with a handful of links; use footer-minimal or footer-columns
  • App screens, where a footer should stay out of the way

Agent notes

  • Server component with plain anchors; swap for next/link if you want client routing
  • The wordmark is aria-hidden and sits at foreground 6 percent
  • Columns collapse to 2 on a phone, 3 at sm, one row at lg