If you want product videos that actually help customers — and don’t slow the page or break accessibility — start by choosing the hosting approach that matches your priorities: ease of embedding, control over bandwidth and privacy, or best performance via a CDN. The rest of the decisions follow from that choice.
In this guide
Decide a hosting strategy
Three common choices work for small shops; pick the one that fits your constraints and confirm details in your provider docs before implementing:
- External video host (YouTube, Vimeo, Wistia) — easiest for embedding, adaptive playback and bandwidth management, but check embedding and branding rules in the provider terms and whether the host allows commercial embedding. If you choose this route, test how the embed behaves on mobile and whether the provider’s player exposes captions and keyboard controls.
- Self‑hosted files (WordPress media / uploads) — fine for short MP4s if your host supports the traffic. WordPress supports several formats and a poster image via the core Video block; read the block and theme guidance before relying on it: see the WordPress Video block docs at Video block documentation and the Theme Handbook media notes at WordPress Theme Handbook: video.
- CDN or streaming (HLS/DASH) via a storage/CDN provider — good for larger catalogs or higher quality playback and signed‑URL access control. Vendor support for HLS/DASH, CORS headers and signed URLs is provider-specific; check your CDN/docs for streaming support and pricing before committing.
Before you pick: check the host or CDN documentation for bandwidth/pricing, embedding restrictions and any CORS or signed-URL options. Don’t assume all hosts permit the same use or offer the same streaming formats.
Implement accessible playback
Accessibility matters commercially: captions and transcripts help customers who are deaf, hard-of-hearing, in noisy places, or who prefer reading. Follow WAI guidance: provide synchronized captions (WebVTT or SRT) and a textual transcript on the same page or a clearly linked page. See WAI’s guidance on transcripts and captions at W3C WAI: Transcripts and Captions.
Practical playback requirements to test on staging:
- Captions loaded and synchronised (WebVTT is widely supported); provide a separate full transcript beneath or next to the player.
- Keyboard operable controls (play/pause, volume, seek) and visible focus states; the player should expose a visible play/pause control that can be reached by Tab and activated with Enter/Space.
- Provide a clickable transcript or a “View transcript” link close to the player so keyboard and screen‑reader users can find it quickly.
Add Video structured data correctly
Only add a VideoObject when the page actually contains the video or an embedded player. Follow the Video structured-data guidance for required and recommended properties (name, description, thumbnailUrl, uploadDate, duration and either contentUrl or embedUrl). Google’s developer documentation explains the expected fields and testing workflow: Google: Video structured data. For the schema vocabulary reference see schema.org: VideoObject.
Keep these points in mind:
- Use
contentUrlwhen a direct, fetchable video file is available to crawlers; useembedUrlfor an embedded player (YouTube/Vimeo-style) when the file URL is not appropriate. - Include
thumbnailUrl,uploadDateanddurationwhere possible; they are high-value properties for eligibility. - Adding markup makes the page eligible for certain search features; it does not guarantee a special result or placement.
Copyable JSON‑LD template (replace placeholders):
{
"@context": "https://schema.org",
"@type": "VideoObject",
"name": "{{Short video title}}",
"description": "{{One-sentence description of the video content}}",
"thumbnailUrl": "https://example.com/path/to/thumbnail.jpg",
"uploadDate": "2026-09-01",
"duration": "PT1M30S",
"contentUrl": "https://example.com/path/to/video.mp4",
"embedUrl": "https://player.example.com/embed/VIDEO_ID"
}
Optimize loading and LCP impact
Videos and heavy player scripts can harm Largest Contentful Paint. Two practical rules:
- If the poster image (the still shown before playback) is the page’s LCP element, don’t lazy-load it. Make sure it’s available to the browser quickly so LCP isn’t delayed.
- Defer heavy player JavaScript until the user interacts (click‑to‑load) unless you must render a visible, crawlable player immediately. Use viewport-triggered lazy-loading (IntersectionObserver or the browser’s native loading) for non-LCP players. Google’s guidance on lazy-loading and crawlers explains these trade-offs: Google: Lazy-loading and indexing.
On WordPress, test whether your theme or a plugin injects player scripts or lazy-loading behaviour; those can change which resource becomes LCP. If you can’t control the theme, test on a staging copy and document what the theme does before changing the live site.
Test on staging and validate
Do all changes on a staging environment that mirrors the live stack. Checklist of reader-run checks you must perform:
- Embed the video on a staging product page using your chosen hosting option and confirm captions and a transcript are present and readable.
- Keyboard-only test: Tab to the player, use Enter/Space to play/pause and check that seek and volume controls are reachable and announced by a screen reader.
- Run a structured-data check using Google’s structured-data testing guidance and URL Inspection to confirm the markup is valid and that the page is indexed as expected. See Google: Video structured data.
- Run a performance audit (Lighthouse/PageSpeed) on staging before and after deferring player scripts to confirm the LCP and script-load improvements.
Record screenshots, the staging URL and the specific tests you ran. That makes it easier to reproduce and to troubleshoot if something changes after deployment.
Quick checklist
- Choose hosting: external host, self-hosted MP4 or CDN/streaming — check provider docs for bandwidth, embedding rules and streaming support.
- Provide synchronized captions (WebVTT) and a visible transcript on the page (WAI guidance: W3C WAI: Transcripts and Captions).
- Ensure keyboard-accessible controls, visible play/pause and a transcript link near the player.
- Add VideoObject markup only when the player or video file is present; include name, description, thumbnailUrl, uploadDate and duration. Validate with Google’s structured-data testing workflow: Google: Video structured data and the schema vocabulary at schema.org: VideoObject.
- Don’t lazy-load a poster used as LCP; defer heavy player scripts where feasible and test LCP with Lighthouse.
- Test playback and accessibility on desktop and phone, with keyboard-only navigation and a screen reader, on staging before publishing.
Fictional example (labelled)
Fictional shop: The KnitCo embeds a 90-second demo hosted on a CDN. On staging they upload a WebVTT captions file, add a one-paragraph transcript beneath the player, and use a small poster image that is loaded without lazy-loading because it’s the product-page LCP. They add a VideoObject JSON‑LD using contentUrl for the CDN MP4 and include thumbnailUrl, duration and uploadDate. On staging they confirm keyboard play/pause with Tab and Enter, run a Lighthouse report to verify LCP remains acceptable, and validate the markup with Google’s structured-data testing workflow. This is an illustrative scenario, not a recorded test.
Two related, already‑live guides you may find helpful: Validate product structured data with Google’s Rich Results Test and URL Inspection and Improve product‑page LCP and image performance without re‑shooting photos.
Decide the hosting option first, run the staging checklist above and publish only after captions, transcript, schema validation and a Lighthouse check pass on the staging URL.

