A product photo sits on a page with no alt text at all. It renders fine, loads fast, looks exactly right to a shopper scrolling past it. Google reads nothing about what the photo actually shows beyond a filename like DSC4021.jpg, so the page never surfaces when someone searches for the exact product in that photo. The image works for every visitor except the one deciding whether the page ranks at all.
The same blindness shows up under a different name in every other format on a page: a video with no captions, a podcast with no transcript, a PDF that has never once surfaced in a search result, an SVG icon a screen reader quietly skips past. The content itself is fine in every case. What is missing is one small piece of text, sitting in whichever place that particular format happens to expect it. This is the same layer a build never checks, spread across five formats instead of one.
Images
The image renders correctly, but the alt attribute is empty, the file is 1.8MB served as a JPEG with no width or height set, and lazy loading is switched on for everything, including the hero. None of this is visible in the browser. Google reads the alt text to understand what the image contains, and the file size alone adds seconds to LCP. The missing dimensions cause layout shift, and the lazy-loaded hero is the exact element Google is timing for LCP.
Alt text
Alt text is how Google understands what an image contains. It is also what a screen reader announces and what shows when the image fails to load. Describe what is actually in the image. Do not open with "Image of" or "Photo of", and do not stuff keywords into it.
- An empty
alt=""tells Google the image is decorative and should be ignored, which is correct for a genuinely decorative image. - An absent
altattribute tells Google nothing. It is treated as a missing signal, not a decorative one.
Modern formats
JPEG and PNG are the baseline. WebP is typically 25 to 35 percent smaller than JPEG at the same visual quality. AVIF is smaller still, often around 50 percent smaller, with slightly less universal support. The <picture> element and the srcset attribute let the browser pick the best format it supports.
File size and LCP
Every byte of the LCP image is time spent downloading before the page feels loaded. A 2MB hero image on a 4G connection can take three to six seconds to arrive. Compress before deploying with a tool like Squoosh or ImageOptim, or a CDN that does it automatically: target under 200KB for hero images and under 100KB for smaller content images. A browser does not resize a large image for you. A 4000px image served into a 400px container still downloads at 4000px; the browser shrinks the display, not the transfer.
Width, height, and layout shift
Every image needs explicit width and height attributes. The browser uses them to reserve space before the image loads. Without them, the page renders the surrounding content and jumps when the image arrives, and that jump is CLS. The attributes set the aspect ratio the browser reserves; CSS still controls how large the image actually appears.
Lazy loading
loading="lazy" defers loading until an image is near the viewport. Use it on everything below the fold. Never use it on the LCP image: the browser defers loading the exact element Google is timing, and the score collapses.
Image discovery through the page HTML is usually enough, but a sitemap can also carry image metadata directly. The syntax and size limits for that are covered in sitemaps and robots.txt.
Video
Google cannot watch a video. It reads captions, a transcript, structured data, and the sitemap entry pointing at the file. A video with none of that is functionally invisible to search, no matter how good the content is.
Hosting versus embedding
Self-hosting gives full control over the file and the page around it, but the site now serves the bandwidth for every playback, and building a working player is on you. Embedding through YouTube or Vimeo offloads bandwidth and playback entirely, at the cost of sending some engagement data to another platform and losing a portion of visual control over the player.
<!-- Direct file, hosted on your own domain -->
<video:content_loc>https://example.com/video.mp4</video:content_loc>
<!-- Embeddable player, e.g. a YouTube or Vimeo embed URL -->
<video:player_loc>https://www.youtube.com/embed/VIDEO_ID</video:player_loc>Captions and transcripts
A caption file, most commonly in WebVTT format, gives both a screen reader and a crawler the spoken content as text. A full transcript placed on the page does the same thing at paragraph scale: it turns audio content into indexable text Google can match against a search query the video itself gives no textual trace of.
WEBVTT
00:00:01.000 --> 00:00:04.000
Welcome back. Today we're unboxing the new wireless keyboard.
00:00:04.500 --> 00:00:08.000
The first thing you'll notice is how thin
the aluminum body actually is.VideoObject structured data
Schema.org's VideoObject type gives Google the metadata it needs to show a video thumbnail directly in search results, separate from whatever the sitemap declares.
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "VideoObject",
"name": "Wireless keyboard unboxing and first look",
"description": "A hands-on look at the aluminum body and battery life.",
"thumbnailUrl": "https://example.com/thumb.jpg",
"uploadDate": "2026-08-01T00:00:00Z",
"duration": "PT8M12S",
"contentUrl": "https://example.com/video.mp4"
}
</script>duration uses ISO 8601 duration format: PT8M12S is 8 minutes 12 seconds. Missing thumbnailUrl is the most common reason a video qualifies for indexing but never gets a rich thumbnail in results. The sitemap-level tags for video, <video:video> and its required fields, are covered in sitemaps and robots.txt.
Audio and podcasts
Audio fails the same way video does, minus even the thumbnail. Google cannot listen. Without a transcript or structured data, an audio file is a URL with no readable content behind it at all.
ID3 tags versus page metadata
An MP3 file carries its own metadata internally, called ID3 tags: title, artist, album, cover art. These live inside the audio file itself, the same way a PDF carries its metadata inside the PDF rather than in the page around it. A crawler reading the HTML page never sees ID3 tags unless the page also states that information as visible text.
Podcast RSS feeds
A podcast is discovered through its RSS feed, not through a sitemap. The feed uses a separate namespace with its own required fields, distinct from anything in Schema.org.
<item>
<title>Episode 12: Why remote teams overinvest in tools</title>
<description>Tool sprawl slows teams down more often than it speeds them up.</description>
<enclosure url="https://example.com/ep12.mp3" type="audio/mpeg" length="24500000" />
<itunes:duration>00:28:14</itunes:duration>
<itunes:image href="https://example.com/ep12-cover.jpg" />
<pubDate>Mon, 10 Aug 2026 09:00:00 GMT</pubDate>
</item>enclosure is the required pointer to the actual audio file and its byte length. Missing or wrong length causes some podcast apps to reject the episode outright rather than degrade gracefully.
Transcripts index the episode
A full transcript published on the episode page is what actually gets a podcast found through a search query about its content, the same mechanism as video captions. Some platforms auto-generate a transcript behind the scenes, but it is rarely published as crawlable text on the episode's own page. A transcript placed directly on the page is the only version guaranteed to be indexed.
A PDF is not an HTML document. It has no <head>, no meta description, no canonical tag, no OpenGraph image. Every mechanism covered in meta tags simply does not apply. Whatever metadata a PDF carries lives inside the file itself.
Where PDF metadata actually lives
PDF Document Properties, sometimes called the Info dictionary, holds a small set of fields set through the authoring tool or a library at export time, not written as markup.
Title: what Google most often shows as the search result title for a PDF, in place of guessing from the first line of visible text.Author: rarely surfaced in results, occasionally used for attribution.Subject: the closest equivalent to a meta description, though Google treats it as a much weaker signal.Keywords: the same dead field HTML abandoned. No effect on ranking.
These are set in the export dialog of the authoring tool, or programmatically with a library like pdf-lib or PyPDF2, not written as tags in any markup a browser would parse.
Why PDFs tend to rank worse
A PDF is one long document with one URL, and no per-section metadata of any kind. Canonicalizing a duplicate needs an HTTP Link header, Link: <url>; rel="canonical", since there is no <head> for the usual tag to sit in, and most hosting setups never configure it. Text extraction depends entirely on how the PDF was produced. A PDF exported from a scanned image contains no extractable text at all unless OCR was run on it first, in which case Google is reading text nobody actually wrote as text.
Accessibility works differently too
There is no alt attribute inside a PDF. Accessibility instead requires a tagged PDF, conforming to the PDF/UA standard, where headings, reading order, and image descriptions are embedded as a structural tag tree. An untagged PDF is close to unreadable for a screen reader, regardless of how it looks visually. For content that matters for search or for accessibility, publishing it as an HTML page and offering the PDF as a secondary download is almost always the better default.
SVG
An SVG is markup, not a binary image, which means it can carry its own accessible text directly inside the file, something no other image format can do.
title and desc elements
<svg role="img" aria-labelledby="icon-title" viewBox="0 0 24 24">
<title id="icon-title">Search</title>
<desc>A magnifying glass icon used for the search action.</desc>
<path d="..." />
</svg><title> is announced by a screen reader the same way alt text is on an <img>. <desc> adds a longer description for more complex graphics, a chart or a diagram rather than a simple icon.
Inline SVG versus an external file
An SVG written directly into the HTML, inline, is part of the DOM. Its title and desc are read directly by both a crawler and a screen reader. An SVG referenced as <img src="icon.svg"> is treated as an opaque image; its internal title and desc are not exposed to accessibility tools at all, and the img tag needs its own alt attribute to carry that information instead.
What the build process will not tell you
No build step fails for an image with no alt text, a video with no captions, a podcast with no transcript, or a PDF with no title metadata. Nothing flags an SVG with no accessible label either. Every one of these renders, plays, or opens exactly as intended, correct to a sighted visitor with working ears, while staying close to unreadable to the visitor that actually decides whether the page ranks at all.
Lighthouse catches missing image alt text and can flag some accessibility gaps in inline SVG. PDF metadata and video captions need checking by hand instead, one file at a time. No deploy pipeline reaches that layer at all.