---
title: "VideoObject Schema Markup API and JSON-LD · Unhead"
canonical_url: "https://unhead.unjs.io/docs/react/schema-org/api/schema/video"
last_updated: "2026-09-09T05:26:53.804Z"
meta:
  description: "Create VideoObject schema markup with defineVideo. Learn required video metadata, thumbnails, upload dates, clips, and JSON-LD examples."
  "og:description": "Create VideoObject schema markup with defineVideo. Learn required video metadata, thumbnails, upload dates, clips, and JSON-LD examples."
  "og:title": "VideoObject Schema Markup API and JSON-LD · Unhead"
---

Home

`
Unhead on GitHub

Switch to ReactSwitch to TypeScriptSwitch to VueSwitch to SvelteSwitch to Solid.jsSwitch to AngularSwitch to Nuxt

**Schema**

# **VideoObject Schema Markup API and JSON-LD**

[Copy for LLMs](https://raw.githubusercontent.com/unjs/unhead/refs/heads/main/docs/schema-org/5.api/9.schema/video.md)

## **Implementation overview **

Use defineVideo() to publish complete VideoObject structured data. This reference explains names, descriptions, thumbnails, upload dates, durations, content URLs, clips, and TypeScript examples.

## Schema.org Video

- **Type**: `defineVideo<T extends Record<string, any>>(input?: VideoObject & T)`  
  Describes an individual video (usually in the context of an embedded media object).

## Useful Links

- [**~~VideoObject - Schema.org~~**](https://schema.org/VideoObject)
- [**~~Video Structured Data - Google Search Central~~**](https://developers.google.com/search/docs/appearance/structured-data/video)

## Google and input properties

- **name** `**string**`  
  The title of the video. Google requires this property for video rich results.  
  Route metadata on the `**title**` key can provide this value; see [**~~Defaults~~**](#defaults).
- **description** `**string**`  
  A description of the video. Google recommends this property. Unhead falls back to `**caption**`, then to `**No description**`.  
  Route metadata on the `**description**` key can provide this value; see [**~~Defaults~~**](#defaults).
- **thumbnail** `**ImageObject**`  
  An optional ImageObject reference for the video thumbnail.  
  Page image metadata is inherited separately as `**image**`. Set `**thumbnailUrl**` explicitly when targeting Google's video feature.
- **thumbnailUrl** `**string | string[]**`  
  A URL pointing to the video thumbnail image file. Google requires this property for video rich results; follow the [**~~thumbnail image guidelines~~**](https://developers.google.com/search/docs/appearance/video#valid-thumbnail).
- **uploadDate** `**string**`  
  The date the video was published, in ISO 8601 format. Google requires this property for video rich results.  
  Route metadata on the `**datePublished**` key can provide this value; see [**~~Defaults~~**](#defaults).
- **url** `**string**`  
  An optional video file or page URL used by Unhead. Relative values are resolved against the configured host.  
  Google does not require this property when `**contentUrl**` or `**embedUrl**` is available.
- **contentUrl** `**string**` or **embedUrl** `**string**`  
  Google recommends the URL of the video bytes in `**contentUrl**`, or a player URL in `**embedUrl**` when the content URL is unavailable. Unhead resolves relative values against the configured host.
- **hasPart** `**Clip | Clip[]**`  
  Add named key moments with `**name**`, `**startOffset**`, `**url**`, and optional `**endOffset**`.
- **publication** `**BroadcastEvent | BroadcastEvent[]**`  
  Add livestream timing with `**isLiveBroadcast**`, `**startDate**`, and optional `**endDate**`.
- **potentialAction** `**SeekToAction**`  
  Describe the timestamp URL pattern used for automatic key moments.
- **expires**, **interactionStatistic**, **ineligibleRegion**, and **regionsAllowed**  
  These properties cover expiry, view counts, and regional availability.

## Defaults

- **@type**: `**VideoObject**`
- **@id**: `**${canonicalHost}#/schema/video/{n}**`
- **name**: `**title**` from resolved page metadata
- **description**: resolved page description, then `**caption**`, then `**No description**`
- **image**: `**image**` from resolved page metadata
- **inLanguage**: `**inLanguage**` from resolved page metadata
- **uploadDate**: `**datePublished**` from resolved page metadata

## Resolves

See [**~~Global Resolves~~**](https://unhead.unjs.io/docs/schema-org/guides/get-started/overview#how-does-schemaorg-get-page-data) for full context.

- `**url**`, `**contentUrl**`, `**embedUrl**`, Clip URLs, SeekToAction targets, and each `**thumbnailUrl**` are resolved to absolute URLs
- `**uploadDate**`, `**expires**`, and BroadcastEvent dates accept Date objects and are serialized as ISO 8601 strings
- a string input is cast to `**{ url: input }**`

## Example

```
defineVideo({
  name: 'My cool video',
  description: 'A short demonstration video.',
  thumbnailUrl: '/video-thumbnail.png',
  uploadDate: new Date(Date.UTC(2020, 10, 10)),
  contentUrl: '/video.mp4',
  hasPart: {
    name: 'Introduction',
    startOffset: 0,
    url: '/videos/demo?t=0',
  },
})
```

## Types

```
export interface VideoSimple extends Thing {
  /**
   * The title of the video.
   */
  name?: string
  /**
   * A description of the video (falling back to the caption, then to 'No description').
   */
  description?: string
  /**
   * A reference-by-ID to an imageObject.
   */
  thumbnail?: NodeRelation<ImageObject>
  /**
   * A URL pointing to the video thumbnail image file. Follow the [thumbnail image guidelines](https://developers.google.com/search/docs/appearance/video#valid-thumbnail).
   */
  thumbnailUrl?: Arrayable<string>
  /**
   * The date the video was published, in ISO 8601 format (e.g., 2020-01-20).
   */
  uploadDate?: ResolvableDate
  /**
   * Whether the video should be considered 'family friendly'
   */
  isFamilyFriendly?: boolean
  /**
   * The URL of the video file or page.
   */
  url?: string
  /**
   * The fully qualified, absolute URL of the video file.
   */
  contentUrl?: string
  /**
   * A text caption for the video.
   */
  caption?: string
  /**
   * The height of the video in pixels.
   * - Must be used with width.
   */
  height?: number
  /**
   * The width of the video in pixels.
   * - Must be used with height.
   */
  width?: number
  /**
   * The language code for the textual content; e.g., en-GB.
   * - Only needed when providing a caption.
   */
  inLanguage?: string
  /**
   * The duration of the video in ISO 8601 format.
   */
  duration?: string
  /**
   * A URL pointing to a player for the video.
   */
  embedUrl?: string
  /**
   * The encoding format of the video.
   */
  encodingFormat?: string
  /**
   * A transcript of the video.
   */
  transcript?: string
  expires?: ResolvableDate
  ineligibleRegion?: Arrayable<string>
  regionsAllowed?: Arrayable<string>
  interactionStatistic?: NodeRelations<InteractionCounter>
  hasPart?: NodeRelations<Clip>
  publication?: NodeRelations<BroadcastEvent>
  potentialAction?: NodeRelation<SeekToAction>
}
```

[Edit this page](https://github.com/unjs/unhead/edit/main/docs/schema-org/5.api/9.schema/video.md)

[Markdown For LLMs](https://raw.githubusercontent.com/unjs/unhead/refs/heads/main/docs/schema-org/5.api/9.schema/video.md)

**Did this page help you? **

[**VacationRental Schema** Add Google vacation rental structured data with defineVacationRental(), including accommodation, location, amenities, beds, ratings, and reviews.](https://unhead.unjs.io/docs/schema-org/api/schema/vacation-rental) [**WebPage Schema** Use defineWebPage() to add WebPage structured data. Connect page content to your site hierarchy with automatic page type detection.](https://unhead.unjs.io/docs/schema-org/api/schema/webpage)

**On this page **

- [Schema.org Video](#schemaorg-video)
- [Useful Links](#useful-links)
- [Google and input properties](#google-and-input-properties)
- [Defaults](#defaults)
- [Resolves](#resolves)
- [Example](#example)
- [Types](#types)