MKT UI
Sections

Split hero

Headline and supporting copy beside an image. The default page opener.

Open preview (opens in a new tab)

Installation

npx shadcn@latest add http://localhost:3000/r/hero-split.json

MKT UI is not published yet, so this points at your local development server. Set NEXT_PUBLIC_REGISTRY_URL to the deployed origin to show the public command.

Also installs: container, section, cta-group, media-frame.

Usage

import { Button } from "@/components/ui/button";
import { HeroSplit } from "@/components/hero-split";

<HeroSplit
  eyebrow="Licensed & insured"
  title="Plumbing problems fixed properly, the first time."
  description="Same-day emergency slots across north Austin, upfront pricing, and a six-year workmanship warranty."
  actions={
    <>
      <Button asChild>
        <a href="#quote">Request a quote</a>
      </Button>
      <Button variant="outline" asChild>
        <a href="tel:+15125550142">Call (512) 555-0142</a>
      </Button>
    </>
  }
  note="Free quotes · No call-out fee on scheduled work"
  image={{ src: "/hero.jpg", alt: "Technician fitting a copper pipe" }}
/>

Props

PropTypeDefaultDescription
title (required)ReactNodeThe headline. Rendered as the page's h1 — use this section once per page.
eyebrowReactNodeShort label above the headline. Good for a credential or category, not a second sentence.
descriptionReactNodeOne or two sentences on what you do and who for.
actionsReactNodeButtons or links. Put the action you most want taken first — it is also the first tab stop.
noteReactNodeReassurance under the actions, e.g. "Free quote · No obligation".
proofReactNodeProof below the actions — a rating, a logo strip, a credential row.
image{ src, alt, caption? }Convenience image. Ignored when `media` is supplied.
mediaReactNodeRender your own media instead: a next/image with fill, a video, a screenshot frame.
reversebooleanfalsePut the media on the left on wide screens. DOM order does not change.
surface"default" | "muted" | "brand" | "inverted""default"Background treatment.

Behavior

Copy always comes first in the DOM. reverse moves the image visually with CSS order, but the markup order never changes. On a phone the visitor reaches the headline and call to action without scrolling past a large image, and keyboard and screen-reader users get the same sequence.

The hero image loads eagerly. It is above the fold, so the built-in MediaFrame uses loading="eager" and fetchPriority="high". If you pass your own media, set those yourself — a lazy-loaded hero image is a Largest Contentful Paint problem.

Space is reserved before the image loads. The frame has a fixed aspect ratio, so the page does not jump when the image arrives.

Using next/image

The section stays framework-neutral, but nothing stops you passing an optimized image:

import Image from "next/image";

<HeroSplit
  title="…"
  media={
    <MediaFrame aspect="square">
      <Image src={heroImage} alt="…" fill priority className="object-cover" />
    </MediaFrame>
  }
/>

Limitations

  • No built-in background-image or video variant. Those are separate sections (hero-background, hero-video) and are not implemented yet.
  • proof is an open slot rather than a structured prop. A dedicated rating and logo strip component is planned.
  • The two-column split becomes one column below lg (1024px). There is no option for a three-column hero.

On this page