Hero

A hero is the first thing on a marketing or documentation home page. It renders a <section> with an <h1> inside — so it is the page’s heading, not a decorative banner that happens to be large.

Basic hero

Static sites, without the framework

Write functions that return HTML. Get a complete site.

hero({
  level: 2,
  title: 'Static sites, without the framework',
  description: 'Write functions that return HTML. Get a complete site.',
},
  button({ size: 'lg' }, 'Get started'),
  button({ size: 'lg', variant: 'outline', color: 'neutral' }, 'Read the docs'),
)

With an eyebrow

A short line above the title — a version, a category, an announcement.

sitelo 2.7

Now with a component library

Seventy components, no runtime, one optional script.

hero({
  level: 2,
  eyebrow: 'sitelo 2.7',
  title: 'Now with a component library',
  description: 'Seventy components, no runtime, one optional script.',
},
  button({ size: 'lg', href: '/ui' }, 'Browse the components'),
)

Left aligned

Open source

Built in the open

MIT licensed, and small enough to read in an afternoon.

hero({
  level: 2,
  align: 'start',
  eyebrow: 'Open source',
  title: 'Built in the open',
  description: 'MIT licensed, and small enough to read in an afternoon.',
},
  button({ href: 'https://github.com/paul-browne/sitelo' }, 'View on GitHub'),
)

With media

Passing media switches to two columns once there is room for them, and stacks back to one on a narrow screen. It pairs naturally with mockup().

See it running

Every page is static HTML by the time it reaches the browser.

example.com
Hello world

Rendered at build time.

hero({
  level: 2,
  align: 'start',
  title: 'See it running',
  description: 'Every page is static HTML by the time it reaches the browser.',
  media: mockup({ variant: 'browser', url: 'example.com' },
    div({ style: 'padding: 1.5rem; background: var(--su-surface-2)' },
      text({ variant: 'h5', as: 'div' }, 'Hello world'),
      text({ variant: 'small', tone: 'muted' }, 'Rendered at build time.'),
    ),
  ),
},
  button('Get started'),
)

Inside a container

A hero has no width limit of its own — put it in a container() so it lines up with everything else on the page.

Contained

The container sets the width; the hero sets the rhythm.

container({ size: 'md', style: 'background: var(--su-surface-2); border-radius: 0.6rem' },
  hero({
    level: 2,
    title: 'Contained',
    description: 'The container sets the width; the hero sets the rhythm.',
  }),
)

Heading level

The title is the page <h1> by default, which is right for a landing page. A hero used part way down a page is not the page heading, so lower it with level — every demo on this page does, since the page already has an h1 of its own.

Just a title

Every part is optional, and nothing empty is rendered.

Documentation

hero({ level: 2, title: 'Documentation' })

Props

PropTypeDefaultDescription
eyebrowChildSmall uppercase line above the title.
titleChildRendered as the page h1.
descriptionChildThe sentence under it.
mediaChildBeside the text on a wide screen, above it on a narrow one.
align'center' | 'start''center'Text alignment when there is no media.
levelnumber1Heading level for the title. Lower it for a hero part way down a page.
asstring'section'Element to render.

Children become the action row under the description.