Hero
A flexible opening section for landing pages, product pages, and documentation.Hero is a content-led introductory block for product pages, documentation, and landing pages. It combines an optional eyebrow, primary heading, supporting description, actions, and optional media.
Variants and behaviour
The centered layout keeps attention on a concise message; the split layout makes room for media or a supporting panel beside the copy.
Customization
Compose action links through the actions array and place any product visual in the media snippet. Keep the textual props semantic and let the surrounding page control width and spacing.
Examples
Installation
Install Fractalsvelte, then import the block from the dedicated blocks entry point.
Install
pnpm add fractalsvelteImport
<script lang="ts">
import { Hero } from 'fractalsvelte/blocks';
</script>Usage
Usage
<script lang="ts">
import { Hero } from 'fractalsvelte/blocks';
</script>
<Hero title="Build with confidence" description="Composable Svelte building blocks." />Props
| Prop | Type | Default | Description |
|---|---|---|---|
eyebrow | string | - | Small contextual label above the title. |
title | string | - | Primary page message. |
description | string | - | Supporting description. |
actions | HeroAction[] | [] | Optional action links. |
layout | 'centered' | 'split' | 'centered' | Content alignment pattern. |
media | Snippet | - | Optional media region for split layout. |
Source
Block source is published with the package and can be inspected here.
Hero.svelte
<script lang="ts">
import type { Snippet } from 'svelte';
interface Action { label: string; href: string; variant?: 'primary' | 'secondary'; }
interface Props { eyebrow?: string; title: string; description: string; actions?: Action[]; layout?: 'centered' | 'split'; media?: Snippet; }
let { eyebrow, title, description, actions = [], layout = 'centered', media }: Props = $props();
</script>
<section class="hero" data-layout={layout}>
<div class="hero-copy box gap16">
{#if eyebrow}<span class="text-sm col2">{eyebrow}</span>{/if}
<h1>{title}</h1><p>{description}</p>
{#if actions.length}<div class="row gap8 wrap">{#each actions as action (action.href)}<a class:btn-primary={action.variant !== 'secondary'} class:btn-secondary={action.variant === 'secondary'} href={action.href}>{action.label}</a>{/each}</div>{/if}
</div>
{#if media}<div class="hero-media">{@render media()}</div>{/if}
</section>
<style lang="sass">
.hero
background: var(--color10)
border: 1px solid var(--border-tertiary)
border-radius: 6px
padding: 32px
text-align: center
transition: grid-template-columns 200ms ease, text-align 200ms ease
p
color: var(--text-secondary)
font-size: var(--text-lg)
margin: 0
.hero[data-layout='split']
display: grid
gap: 32px
grid-template-columns: repeat(2, minmax(0, 1fr))
text-align: left
.hero-media
min-width: 0
@media (max-width: 720px)
.hero[data-layout='split']
grid-template-columns: 1fr
@media (prefers-reduced-motion: reduce)
.hero
transition: none
</style>
