If a link shows up in WhatsApp as a bare URL, with no picture and no title, the cause is nearly always the page, not the app. WhatsApp builds a link preview from the Open Graph tags in your page’s HTML. Meta publishes the rules for WhatsApp, and they are more specific than most guides say. The tags must sit in the <head>, within the first 300 KB of the HTML. The image must be an absolute URL, under 600 KB, and at least 300 pixels wide. What Meta does not publish matters as much: how long a preview is cached, how to refresh one, and how redirects are handled. This page keeps the two apart, and labels the workarounds as workarounds.
Start with what your page actually sends. The free Open Graph checker reads the tags on any URL, checks the image, and draws the card for WhatsApp and the other big apps. If you are sending the link rather than running the site, jump to the last two rows of the causes table.
All four come from Meta’s WhatsApp link previews page[1]. No study figures are used here, because nobody publishes measured data on WhatsApp previews.
What a link preview is
Meta describes how WhatsApp draws each part. The og:title appears “in bold and in at most 2 lines”. The og:description appears smaller, in a secondary colour, and “is limited to 1 or 2 lines and 80 characters will suffice”. The og:image becomes the thumbnail[1]. Previews work for links sent in a chat and for links shared to Status.
There are two sizes of card. When the image meets Meta’s rules, the card is large. When it does not, WhatsApp may relax the rules, look for other markup, or fall back to a small preview. Meta adds that “this should not be relied on”[1]. So a small card with a tiny thumbnail usually means an image problem, not a tag problem.
How WhatsApp builds the card
Meta’s page describes the process from the sender’s side. Knowing the order explains symptoms that otherwise look random.
Steps 1 to 4 and the 10 seconds are Meta’s[1]. The last sentence of step 5 is our reading: the card is built before you tap send, so it is part of what gets sent.
Two details from WhatsApp’s own help centre change how you debug. WhatsApp has a setting called Disable link previews. With it on, “the links you send to others won’t generate a link preview”, and WhatsApp calls it “an optional layer of security to protect your IP address”. It adds that the setting “doesn’t impact links that you receive from others” and that “receiving link previews has no impact on your IP address”[2]. Put that next to Meta’s “on behalf of the sender”, and our reading is that the request is tied to the sender’s connection. It is not a crawler visiting on a schedule.
Your server sees WhatsApp’s own user agent. Meta’s crawler page lists FacebookExternalHit for Facebook, Instagram and Messenger, and does not mention WhatsApp[5]. The request also carries an Accept-Language header “set to the language selected by the recipient, if any”[1]. If your site picks a language from that header, the card can come out in a language you did not expect.
The Open Graph tags WhatsApp reads
Meta’s WhatsApp page names four tags and gives a rule for each[1]. They are the standard Open Graph tags[6], so one set serves WhatsApp, Facebook, LinkedIn, Slack and iMessage.
| Meta's rule | On screen | |
|---|---|---|
| og:title | Inside <head>, not empty. The title without branding | Bold, at most 2 lines |
| og:description | Inside <head>, not empty | Smaller text, 1 or 2 lines. 80 characters will suffice |
| og:url | Inside <head>, not empty. The canonical URL, with no session or tracking parameters | Meta does not say |
| og:image | An absolute URL. Under 600 KB, at least 300 px wide, 4:1 or narrower | The thumbnail. Large card when the rules are met |
Here is a complete set you can copy and edit. Every URL in it is absolute.
<head> <!-- Put these near the top of <head>, in the HTML your server sends --> <meta property="og:title" content="Trail running for beginners" /> <meta property="og:description" content="Shoes, pacing and safety for your first trail run." /> <meta property="og:url" content="https://www.example.com/guides/trail-running" /> <meta property="og:image" content="https://www.example.com/og/trail-running-v1.jpg" /> <meta property="og:image:type" content="image/jpeg" /> <meta property="og:image:width" content="1200" /> <meta property="og:image:height" content="630" /> <meta property="og:image:alt" content="A runner on a forest trail" /> <meta property="og:type" content="article" /> <meta property="og:site_name" content="Example Outdoors" /> <title>Trail running for beginners | Example Outdoors</title> </head>
The extra tags are optional but useful. og:image:width and og:image:height tell a crawler the size before it downloads the file. Meta’s Facebook guide says they help the image load “the first time it’s shared”[3]. og:image:alt describes the image[6]. Leave your brand out of og:title: Meta asks for the title “without any branding”[1], and Apple suggests og:site_name for the site name instead[8].
Use one og:image. The protocol says that when a tag appears more than once, “the first tag (from top to bottom) is given preference during conflicts”[6]. Meta’s WhatsApp page does not say which one WhatsApp picks, so don’t leave it a choice.
Why a WhatsApp link preview is not showing
Most failures come from one of eleven causes. The last column says who documents the rule: Meta, another platform, or only developers’ reports. Work down the table in order. The early rows are the quickest to check.
| What you see | Fix | Documented by | |
|---|---|---|---|
| Tags missing, empty or outside <head> | Bare URL, no card | Put og:title, og:description, og:url and og:image in the <head> the server sends | Meta |
| Tags added by JavaScript | Bare URL, though the tags show in your browser's inspector | Render the tags on the server | Not by Meta. Apple: Messages runs no JavaScript |
| Relative og:image URL | Title but no image | Use the full https:// address | Meta |
| Image too heavy | No image, or a small card | Under 600 KB. Aim for under 300 KB | 600 KB: Meta. 300 KB: developer reports |
| Image too small or too wide | Small card instead of a large one | At least 300 px wide, no wider than 4:1. 1200 x 630 fits | Meta |
| Tags too far down the HTML | Bare URL on long pages only | Put the meta tags at the top of <head> | Meta: the first 300 KB |
| Bot protection or a login wall | Bare URL, or a card titled like a challenge or sign-in page | Let WhatsApp's user agent through. Check the firewall's event log | Not by Meta. Cloudflare documents the risk |
| Certificate or http problems | Title but no image | Serve the page and image over https with a valid certificate | Developer reports only |
| Redirects | Card for the wrong page, or none | Share the final URL. Make og:url that same URL | Not by Meta. Apple documents Messages |
| Slow page or quick sender | No card when the link is sent at once | Wait up to 10 seconds before sending. Speed up the first response | Meta |
| Sender has previews turned off | No card for one sender only | Turn off Disable link previews in Settings, Privacy, Advanced | WhatsApp Help |
Tags missing, or added by JavaScript
Meta’s rule is plain: the title, description and URL tags “must be inside the <head> tag. They should not be empty”[1]. Check the HTML your server sends, not the page your browser shows after scripts run. Meta says WhatsApp “crawls the web page via an HTTP GET request” and says nothing about running JavaScript[1]. Apple is explicit for iMessage: link previews do not “follow meta redirects, nor run JavaScript”[8]. Next.js puts WhatsApp on its list of HTML-limited bots, which its docs describe as bots “that can’t execute JavaScript”[12][15]. If your app writes its tags with JavaScript, assume WhatsApp never sees them, and render them on the server.
A relative image URL
Meta defines og:image as “an absolute URL”[1]. A path such as /images/card.jpg works inside your site but breaks that rule. Write the full https:// address, or let your framework do it. In Next.js, that is metadataBase, covered below.
An image that is too heavy, too small or too wide
Meta’s numbers: the image “should be under 600KB in size”, and “300px or more in width with 4:1 width/height or less aspect ratio”[1]. A 1200 x 630 image, the size Meta recommends for Facebook[4], passes both shape rules. A 1600 x 300 banner, at about 5.3 to 1, does not.
Meta’s WhatsApp page does not list image formats. Its Facebook guide lists JPEG, GIF and PNG for og:image:type[3]. Oddly, the example on Meta’s WhatsApp page points og:image at an SVG file[1]. We would not copy that. JPEG or PNG is the safe choice.
Tags too far down the HTML
This is the 300 KB rule Meta does publish: the <head> with your tags “must appear within the first 300KB of the HTML. The entire HTML does not need to fit within 300KB”[1]. Large inline scripts, styles or SVG at the top of the head can push the tags past that point. Put the meta tags first. Facebook’s crawler is more generous: Open Graph properties must come before the first 1 MB[5]. That is one way a page can work on Facebook and fail on WhatsApp.
Bot protection, firewalls and login walls
If the preview request gets a challenge page, a sign-in page or a 403, there are no tags to read. Cloudflare says its bot products, though aimed at malicious bots, “may challenge API or mobile app traffic”. On Bot Fight Mode it adds: “You cannot bypass or skip Bot Fight Mode using WAF custom rules or Page Rules.” Exceptions need Super Bot Fight Mode[16]. Cloudflare does have a verified bot category for this traffic, “Link previews for social platforms and messaging apps”[17], but don’t assume any one fetcher is on it. Look in Security, Analytics, Events, where challenged requests are labelled Bot Fight Mode[16], and search for the WhatsApp user agent.
Meta says site owners can identify WhatsApp’s requests by their user agent[1], so a firewall rule that lets them through is possible. Bear in mind that anyone can send that string. For pages behind a login, follow Apple’s advice, which holds for every app: serve tags for the page itself, not for the sign-in page, so the card does not just say “Sign In”[8].
HTTPS and certificates
Meta’s WhatsApp page says nothing about https. The same Stack Overflow answer reports that the image “may not show up if your site runs on https with a self-signed certificate”[7]. That is a developer’s report, not a rule. Serve the page and the image over https with a certificate from a public authority, and the question never comes up.
Redirects
Meta does not document whether WhatsApp follows redirects, or how many. Apple does for iMessage: server-side redirects are followed, meta redirects are not[8]. So share the final URL, make og:url that same URL, and keep any redirect to one server-side hop. The free redirect checker shows every hop. A link that loops is covered in ERR_TOO_MANY_REDIRECTS, and which code to use in 301 vs 302.
What about robots.txt?
Meta’s WhatsApp page does not mention robots.txt. Its crawler page covers FacebookExternalHit, the fetcher for Facebook, Instagram and Messenger. You can address it in robots.txt, but it “might bypass robots.txt when performing security or integrity checks”[5]. Slack says outright: “We do not currently honor robots.txt files”[9]. So robots.txt is not a dependable switch for previews in either direction. If Facebook previews fail too, check you are not disallowing facebookexternalhit. The robots.txt tester checks a file rule by rule.
A slow page, or a quick sender
The card is built while the sender waits. Meta’s own test is to compose the message and wait: “If a preview does not come up above the composer box after 10 seconds, please check all the requirements”[1]. A sender who taps send before the card appears sends no card, and a slow server makes that more likely. Meta asks the same of pages shared to Facebook: they must be crawlable “within a few seconds”[5].
The sender has previews turned off
If one person’s links never show a card while everyone else’s do, check their phone. Disable link previews is off by default and sits under Settings, Privacy, Advanced[2]. It only affects links that person sends.
WhatsApp shows the old preview: caching and refreshing
Start with what is not documented. Meta’s WhatsApp page says nothing about caching, and Meta publishes no tool to refresh a WhatsApp preview[1]. Everything below either follows from how Meta describes the process, or is a workaround that developers use.
Messages already sent keep their card. The card is built in the message box before the sender taps send[1], so it travels with the message. Fixing your page does not change messages that were already delivered, and we know of no way to update them.
New messages can still show an old card. Developers report that apps reuse a stored preview. The top Stack Overflow answer warns that “some apps or websites use a cache or even store the website preview in their database”, so you may see no change straight away, and that “using another link (another page) will do the trick”[7].
?v=2, to the link you share. To any cache it is a new URL, so the page is fetched again. It is a workaround, not a documented method. Fix the page first, or you are only retesting the same broken tags under a new address. Keep og:url pointing at the clean canonical URL, as Meta asks[1].Give a new image a new URL. Facebook caches images by address: “Images are cached based on the URL and won’t be updated unless the URL changes”[3]. Meta does not say the same about WhatsApp, but a new file name such as card-v2.jpg takes the question off the table.
The Sharing Debugger is for Facebook. It shows which tags Facebook’s crawler reads, and it triggers a fresh scrape that can update Facebook’s stored preview[3]. Meta does not say it touches WhatsApp, which sends its own request with its own user agent[1]. Use it to check your tags. Don’t count on it to refresh WhatsApp.
How to preview a URL before you share it
Three checks, quickest first.
1. An Open Graph checker. Paste the URL into the Open Graph checker. It reads the tags in the HTML, checks the image’s format and pixel size, and draws the card for each app. It fetches from our server, so it cannot see WhatsApp’s cache, and its WhatsApp card is a close approximation, not a screenshot from the app.
2. curl, as WhatsApp. Ask your server for the page with WhatsApp’s user agent and look at what comes back. The version string below is one of Meta’s own examples[1].
# 1. Fetch the page the way WhatsApp's Android app identifies itself
# (this version string is one of Meta's own examples)
curl -sSL -A "WhatsApp/2.22.20.72 A" -o page.html \
-w "%{http_code} %{url_effective}\n" https://www.example.com/guides/trail-running
# 2. Which og: tags appear in the first 300 KB of the HTML?
head -c 300000 page.html | grep -o '<meta property="og:[^>]*>'
# 3. How heavy is the image? Look at content-length (bytes) and content-type
curl -sSI -A "WhatsApp/2.22.20.72 A" https://www.example.com/og/trail-running-v1.jpg \
| grep -iE "^HTTP|content-length|content-type"A 403 or 503, a final URL you did not expect, or tags missing from the first 300 KB each point to a row in the table above. A request from your own computer is not a request from a sender’s phone, so a firewall may still treat the two differently.
3. WhatsApp itself. Meta’s method: compose a message with the link, but don’t send it. If no card appears within 10 seconds, a tag rule is failing. If the card is small, check the image rules[1]. Add a new query string each time, so you test the page and not a stored preview.
If you only want to know where a link goes before you open it, the redirect checker shows every hop and the final address, fetched from our server rather than your browser.
Open Graph for WhatsApp in Next.js
Next.js writes the tags for you from a metadata object. Four details decide whether WhatsApp gets a card.
// app/layout.tsx: one base URL, so relative paths become absolute URLs
import type { Metadata } from "next";
export const metadata: Metadata = {
metadataBase: new URL("https://www.example.com"),
};
// app/guides/trail-running/page.tsx
import type { Metadata } from "next";
export const metadata: Metadata = {
title: "Trail running for beginners",
description: "Shoes, pacing and safety for your first trail run.",
openGraph: {
// A page's openGraph replaces the layout's whole openGraph object,
// so repeat everything the card needs here, the image included.
title: "Trail running for beginners",
description: "Shoes, pacing and safety for your first trail run.",
url: "/guides/trail-running",
type: "article",
images: [
{
url: "/og/trail-running-v1.jpg", // becomes https://www.example.com/og/...
width: 1200,
height: 630,
alt: "A runner on a forest trail",
},
],
},
};- metadataBase makes paths absolute. Set it once in the root layout. Next.js combines each relative path with it “to form a fully qualified URL”, and a relative path without it “will cause a build error”[12].
- A page’s openGraph replaces the layout’s. Metadata is “shallowly” merged, so an
openGraphobject set in a layout is “overwritten by the last segment to define them”[12]. A page that setsopenGraphwith only a title loses the layout’s image. Repeat the image, or spread a shared object. - opengraph-image files write the tags for you. A file next to a page adds
og:imagewith its type, width and height. The build only fails above 8 MB[13], far above Meta’s 600 KB for WhatsApp, so check the size of what it produces. - Keep WhatsApp in htmlLimitedBots. When metadata is resolved at request time, Next.js can stream it into the
<body>. Bots on its HTML-limited list get it in the<head>instead[12], and WhatsApp is on the default list[15]. Setting your ownhtmlLimitedBots“will override the Next.js’ default list”[14]. Add crawlers to the default pattern, never in place of it, because Meta wants the tags inside<head>[1]. The Next.js SEO guide covers the same setting for AI crawlers.
Link previews in iMessage, Telegram, Slack and LinkedIn
The same Open Graph tags drive almost every app. What differs is the limits, and how you get a stale card refreshed.
| What it reads | Documented limits | Refreshing a card | |
|---|---|---|---|
| iMessage | og:title and og:image. Without them, a grey bubble with the page title and an icon | Images at least 900 px wide; under 150 px may show as an icon. Page limited to 1 MB. No JavaScript, no meta redirects | Apple does not document one |
| Telegram | Telegram's docs could not be reached to confirm | Not checked | @WebpageBot, which Tilda's help centre calls an official Telegram bot: send it up to 10 links |
| Slack | Open Graph, X (Twitter) Card and oEmbed tags | Fetches as little of the page as it can, with Range headers. Does not honor robots.txt | Responses cached for around 30 minutes |
| Facebook, Instagram, Messenger | Open Graph, read by FacebookExternalHit | Image at least 200 x 200 px and at most 8 MB. Tags within the first 1 MB | Sharing Debugger triggers a new scrape |
| Open Graph | See our LinkedIn post preview guide | Post Inspector |
Sources: iMessage[8]; Telegram[11]; Slack[9][10]; Facebook[4][5][3]. Telegram’s own site did not answer from our network when this was written, so the Telegram row relies on Tilda.
LinkedIn builds its card the same way and keeps it for a while. LinkedIn post preview covers Post Inspector and refreshing. For one image that works in all of these apps, see OG image size, and for every tag in the protocol, the Open Graph protocol guide.
The same HTML feeds AI answers
A link preview and an AI answer have one thing in common. Both are built by software that reads your HTML, with no person watching what it saw. Tags that need JavaScript, or a page hidden behind a challenge, can leave both with nothing. CoreCited’s AI Visibility Tracking covers the second: it asks AI engines the questions your buyers ask, and shows whether your brand is named and cited. The free account includes 5 prompts, and every limit is on the pricing page.
Questions people ask
Why is my WhatsApp link preview not showing?
Usually because WhatsApp could not read the page's Open Graph tags. Check that og:title, og:description, og:url and og:image are in the head of the HTML your server sends, that the image URL is absolute, and that the image is under 600 KB and at least 300 px wide. Then check that bot protection is not blocking WhatsApp's request, and wait up to 10 seconds before you tap send.
What size should a WhatsApp preview image be?
Meta's rules are: under 600 KB, at least 300 pixels wide, and no wider than 4:1. A 1200 x 630 image meets the shape rules. Many developers keep the file under 300 KB to be safe. That figure comes from community testing, not from Meta, but staying under it costs nothing.
How do I refresh a WhatsApp link preview?
Meta publishes no refresh tool for WhatsApp. Messages already sent keep the card they were sent with. For new messages, fix the page first, then share the link with a query string added, such as ?v=2, so it counts as a new URL. That is a workaround developers use, not a documented method.
Does WhatsApp use Open Graph tags?
Yes. Meta's WhatsApp documentation asks for og:title, og:description, og:url and og:image in the page's head. When they are missing, WhatsApp may look for other markup or show a small preview, but Meta says not to rely on that.
Why does my link preview work on Facebook but not on WhatsApp?
They follow different rules. Facebook reads Open Graph tags within the first 1 MB of the page and accepts images up to 8 MB. WhatsApp wants the head within the first 300 KB and the image under 600 KB. WhatsApp also sends its own request with its own user agent, which a firewall can treat differently from Facebook's crawler.
How can I preview a URL before I send it?
Paste it into a WhatsApp message and wait without sending. If the page qualifies, the card appears above the message box within about 10 seconds. To see the tags behind the card, use an Open Graph checker. To see where a link leads without opening it, a redirect checker shows every hop.
