> ## Documentation Index
> Fetch the complete documentation index at: https://docs-loja.usecorvex.com.br/llms.txt
> Use this file to discover all available pages before exploring further.

# Hero com vídeo

> Cookbook — hero section com imagem ou vídeo (biblioteca, upload ou URL) — Golden Path V2.

> Quero um hero que alterna entre imagem e vídeo, com envio pela biblioteca de vídeos da loja. Qual é a implementação recomendada?

Índice: [Cookbooks](https://docs-loja.usecorvex.com.br/cookbook/overview.md) · Hub: [Biblioteca de vídeos](https://docs-loja.usecorvex.com.br/guides/video-library.md)

***

## Contratos utilizados

* [Section Contract](https://docs-loja.usecorvex.com.br/reference/contracts/section.md)
* Fields [`video`](https://docs-loja.usecorvex.com.br/schema/fields/video), [`image`](https://docs-loja.usecorvex.com.br/schema/fields/image), [`select`](https://docs-loja.usecorvex.com.br/schema/fields/select), [`checkbox`](https://docs-loja.usecorvex.com.br/schema/fields/checkbox)
* Snippet `CorvexVideo` — [Padrões](https://docs-loja.usecorvex.com.br/guides/video-patterns.md)

***

## Objetivo

```text theme={"theme":{"light":"github-light","dark":"github-dark"}}
Hero Section
├── mediaMode: image | video
├── heroImage (fallback / poster)
├── heroPoster (capa do vídeo)
├── heroVideo (UUID ou URL)
└── toggles: autoplay, loop, overlay
```

***

## Arquivos

```text theme={"theme":{"light":"github-light","dark":"github-dark"}}
sections/hero-video/
├── section.jsx
├── schema.json
└── styles.css

snippets/corvex-video/
└── snippet.jsx
```

Registre em `theme.json`:

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
"sections": ["hero-video", …]
```

***

## `schema.json`

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "name": "Hero com vídeo",
  "category": "Banner",
  "settings": [
    {
      "id": "mediaMode",
      "type": "select",
      "label": "Tipo de mídia",
      "options": [
        { "value": "image", "label": "Imagem" },
        { "value": "video", "label": "Vídeo" }
      ],
      "default": "image"
    },
    { "id": "heroImage", "type": "image", "label": "Imagem" },
    { "id": "heroPoster", "type": "image", "label": "Poster do vídeo" },
    { "id": "heroVideo", "type": "video", "label": "Vídeo" },
    { "id": "videoAutoplay", "type": "checkbox", "label": "Autoplay", "default": true },
    { "id": "videoLoop", "type": "checkbox", "label": "Loop", "default": true },
    { "id": "showOverlay", "type": "checkbox", "label": "Overlay escuro", "default": true },
    { "id": "title", "type": "text", "label": "Título", "default": "Bem-vindo" },
    { "id": "subtitle", "type": "textarea", "label": "Subtítulo" },
    { "id": "buttonLabel", "type": "text", "label": "Botão" },
    { "id": "buttonUrl", "type": "url", "label": "Link do botão" }
  ]
}
```

***

## `section.jsx`

```jsx theme={"theme":{"light":"github-light","dark":"github-dark"}}
import CorvexVideo from '@corvex/snippets/corvex-video';
import './styles.css';

export default function HeroVideoSection({ settings = {} }) {
  const {
    mediaMode = 'image',
    heroImage,
    heroPoster,
    heroVideo,
    videoAutoplay = true,
    videoLoop = true,
    showOverlay,
    title,
    subtitle,
    buttonLabel,
    buttonUrl,
  } = settings;

  const showVideo = mediaMode === 'video' && heroVideo;
  const poster = heroPoster || heroImage;

  return (
    <section
      className={`hero-video${showOverlay ? ' hero-video--overlay' : ''}`}
    >
      <div className="hero-video__media" aria-hidden={showVideo ? undefined : true}>
        {showVideo ? (
          <CorvexVideo
            value={heroVideo}
            poster={poster}
            autoplay={videoAutoplay}
            muted
            loop={videoLoop}
            controls={false}
            preload="metadata"
            className="hero-video__video"
            ariaLabel={title}
          />
        ) : heroImage ? (
          <img
            src={heroImage}
            alt={title ?? ''}
            className="hero-video__image"
            fetchPriority="high"
          />
        ) : null}
      </div>

      <div className="hero-video__content">
        {title ? <h1 className="hero-video__title">{title}</h1> : null}
        {subtitle ? <p className="hero-video__subtitle">{subtitle}</p> : null}
        {buttonLabel ? (
          <a href={buttonUrl || '#'} className="hero-video__cta">
            {buttonLabel}
          </a>
        ) : null}
      </div>
    </section>
  );
}
```

***

## `styles.css` (trecho)

```css theme={"theme":{"light":"github-light","dark":"github-dark"}}
.hero-video {
  position: relative;
  display: grid;
  place-items: center;
  min-height: 560px;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  color: inherit;
}

.hero-video__media {
  position: absolute;
  inset: 0;
}

.hero-video__image,
.hero-video__video {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.hero-video--overlay::before {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--hero-overlay, transparent);
  z-index: 1;
  pointer-events: none;
}

.hero-video__content {
  position: relative;
  z-index: 2;
  text-align: center;
  padding: 2rem;
}
```

***

## Snippet `corvex-video`

Copie a implementação completa de [Padrões — CorvexVideo](https://docs-loja.usecorvex.com.br/guides/video-patterns.md).

O snippet fica em `snippets/corvex-video/`. O build descobre a pasta. Não entra em `theme.json` → `sections`. Importe com `@corvex/snippets/corvex-video`.

***

## Test plan

1. `corvex validate .` e `corvex build .`
2. `corvex sync --open` — abrir Editor
3. Modo **Imagem** — upload de imagem, hero renderiza `<img>`
4. Modo **Vídeo** → aba **URL** — colar MP4 ou YouTube; hero renderiza player
5. Modo **Vídeo** → aba **Enviar** — upload MP4; aguardar **Pronto**; hero mostra vídeo ou poster
6. Autoplay desligado — vídeo não inicia sozinho
7. Mobile — autoplay só com muted + playsInline
8. Publicar e testar URL publicada (não só canvas)

***

## Erros a evitar

| ❌ | ✅ |
| - | - |
| `<video src={settings.heroVideo}>` com UUID | `CorvexVideo` com classificação |
| Hero sem poster | Campo `heroPoster` ou `heroImage` |
| Só `video` sem `image` | Ambos no schema para fallback |
| Markup fora do contrato | JSX + snippet |

***

## Veja também

* [Biblioteca de vídeos](https://docs-loja.usecorvex.com.br/guides/video-library.md)
* [Performance](https://docs-loja.usecorvex.com.br/guides/video-performance.md)
* [Criar Hero (texto/imagem)](https://docs-loja.usecorvex.com.br/guides/create-hero-section.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.