URL Unfurl Not Working: How to Fix Link Previews on iMessage, Discord & More
When you share a URL in Apple iMessage, iOS fetches the page and displays a compact preview card below the message — title, description, thumbnail. When the URL unfurl is missing, wrong, or stuck on an old version, the cause is almost always in your Open Graph tags or in the way your page is rendered to crawlers.
This guide walks through what URL unfurling actually is, how iMessage URL unfurl differs from other apps (especially Discord), every common reason an iMessage link preview fails, step-by-step fixes, the universal Open Graph best practices that make every preview URL unfurl on Discord and iMessage render reliably, and how to test your URL unfurl without sending a single message.
→ Test your iMessage URL unfurl with TryUnfurl
What Is URL Unfurling?
URL unfurling is the process every modern chat app and social network runs when someone pastes a link. The platform fetches your page, reads Open Graph and Twitter Card tags from the <head>, and renders a preview card — headline, description, thumbnail, site name — right inline in the message.
iMessage runs URL unfurl. So does Discord. So do Slack, WhatsApp, Facebook, LinkedIn, Twitter/X, Microsoft Teams, and Telegram. The mechanics are similar across all of them — the differences are in caching, minimum image sizes, and cache-clearing workflows.
How Different Platforms Handle Unfurling
Every platform does broadly the same thing — fetch, parse, render, cache — but with quirks. Here's how iMessage compares with the other apps you'll most often care about when a preview URL unfurl on Discord and iMessage fails.
| Aspect | iMessage | Discord | Slack |
|---|---|---|---|
| Crawler | facebookexternalhit (Apple reuses Meta's UA) |
Discordbot/2.0 |
Slackbot-LinkExpanding |
| Executes JavaScript | No | No | No |
| Server-side cache | No — per-device only | Yes | Yes |
| Cache-clear mechanism | Delete & re-send | ?v=2 query string |
Delete + re-share |
| Minimum image | 300 × 157 px | 300 × 157 px | ~500 × 262 px for large card |
| Twitter Card tags | Not read | Read as fallback | Read as fallback |
| HTTPS image required | Yes | Yes | Yes |
| Cache-clearing tool | None (per-device) | None (use ?v=2) |
None (re-share) |
The universal rule across all three: Open Graph tags must be in the server-rendered HTML. JavaScript-injected metadata is invisible to every one of them.
How iMessage Generates Link Previews
iMessage uses Apple's server-side fetcher to read metadata from the shared URL. It checks, in priority order:
- Open Graph tags —
og:title,og:description,og:image— the primary source <title>tag — fallback for the headline ifog:titleis absent<meta name="description">— fallback for description text
Like all major messaging platforms, iMessage's fetcher does not execute JavaScript. All meta tags must be present in the raw HTML response from the server for iMessage URL unfurl to render.
Common Reasons iMessage Previews Fail
1. Missing og:title or og:image
iMessage requires og:title to render a preview card. Without it, only the bare URL is shown. Without og:image, the preview renders as text-only with no thumbnail.
2. Image too small or wrong format
iMessage works best with images of at least 300 × 157 px. For a consistent thumbnail experience on iOS, use a square or near-square image crop alongside your standard 1200 × 630 px og:image — iOS often crops wide images to a square thumbnail in the compact thread view.
Supported formats: JPEG and PNG. Avoid WebP for og:image if broad iOS compatibility matters.
3. Page is JavaScript-rendered
iMessage's fetcher reads raw HTML. If your Open Graph tags are injected by React, Vue, Angular, or any other client-side framework, iMessage will not see them. The tags must be present in the server-sent HTML (SSR, SSG, or pre-rendering).
4. og:image URL is not publicly accessible
The image URL must load with a plain GET request and return HTTP 200. No authentication, VPN, or redirects requiring cookies.
5. og:image uses HTTP not HTTPS
iMessage requires HTTPS image URLs. HTTP images are blocked on modern Apple platforms.
6. CDN or server blocks Apple's crawl bot
If your server blocks unfamiliar user-agents or applies aggressive bot-protection rules, iMessage's fetcher may receive an error response and show no preview.
7. Redirect chains
Too many hops (HTTP → HTTPS → www → final URL) can cause the iMessage fetcher to give up before resolving tags. Keep redirects to 1–2 hops.
How to Fix iMessage Link Previews
- Add Open Graph tags to your page's
<head>:
<meta property="og:title" content="Your Page Title" />
<meta property="og:description" content="A concise description." />
<meta property="og:image" content="https://example.com/preview.jpg" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
<meta property="og:url" content="https://example.com/your-page" />
<meta property="og:type" content="website" />
<meta property="og:site_name" content="Your Site Name" />
- Confirm tags are server-rendered — check with
curl:
curl -sL -A "facebookexternalhit/1.1" https://example.com/your-page \
| grep -iE '<meta property="og:'
If the tags don't appear in the output, they are JavaScript-injected and invisible to iMessage. Switch to SSR, SSG, or pre-rendering.
Verify the image is accessible and HTTPS — open your
og:imageURL in a private browser window with no cookies. If it fails to load, iMessage can't fetch it either.Test with TryUnfurl — paste your URL into TryUnfurl to see the iMessage preview tab alongside every other platform. TryUnfurl simulates the same server-side fetch that iMessage performs, shows detected image dimensions, and surfaces any missing Open Graph tags — without sending an iMessage.
Re-send the link to see the updated preview — iMessage caches previews per device and per message thread. After a fix, send the link in a new message (or to a different contact) to get a fresh URL unfurl.
Discord-Specific Solutions
When a preview URL unfurl on Discord and iMessage both fail for the same URL, the fix is usually shared — start with the Open Graph basics above, then handle platform-specific quirks.
Discord-specific moves:
- Cache-bust with
?v=2. Discord caches per URL; query strings create a fresh cache entry. - Check angle-bracket suppression.
<https://example.com>in a Discord message tells Discord to skip the embed — sometimes pasted accidentally. - Image minimum is 300 × 157 px. Tiny images are skipped entirely.
- Discord also reads Twitter Card tags as fallback — useful when iMessage and Discord disagree.
Full Discord-specific playbook: Discord Preview Not Updating — URL Unfurl Guide.
Preview URL Unfurl on Discord and iMessage — Shared Troubleshooting
Because both platforms fetch server-side, don't run JavaScript, and use Open Graph as the primary source, their failure modes overlap almost completely:
| Symptom | iMessage fix | Discord fix |
|---|---|---|
| No preview at all | Add og:title; confirm server rendering |
Same; also check for <URL> suppression |
| No image | Check og:image absolute HTTPS URL, public, ≥ 300 × 157 px |
Same |
| Stale preview | Re-send in a new thread | Append ?v=2 to URL |
| Preview works in Safari/browser but not in-app | Tags are JS-injected | Same |
| Preview blocked entirely | Check WAF for facebookexternalhit / Discordbot |
Same |
The shortest path when the same URL fails on both: fix Open Graph tags server-side, then use the platform-specific cache-bust.
iMessage Preview Caching
iMessage is unique among messaging platforms in that there is no central server-side cache to clear. The preview is generated and stored locally on the recipient's device at the time the message is received.
This means:
- After you fix your og: tags, new shares will immediately show the correct preview.
- Existing messages in existing threads will continue to show the old (stale) preview on recipients' devices.
- The recipient can delete the message and ask you to resend the link to get a fresh preview.
This is different from Facebook (Sharing Debugger), LinkedIn (Post Inspector), and Twitter/X (Card Validator), which all have server-side cache-clearing tools.
iMessage vs. Other Messaging Apps
| Feature | iMessage | Telegram | Slack | |
|---|---|---|---|---|
| Reads og: tags | ✓ | ✓ | ✓ | ✓ |
| Executes JavaScript | ✗ | ✗ | ✗ | ✗ |
| Server-side cache | ✗ (device only) | ✓ | ✓ | ✓ |
| Cache-clearing tool | None | None | None (use ?v=2) |
None (re-paste) |
| Minimum image size | 300 × 157 px | 300 × 200 px | ~200 × 200 px | ~500 × 262 px for large card |
| HTTPS image required | ✓ | ✓ | ✓ | ✓ |
Universal Open Graph Best Practices
These are the rules that make every URL unfurl — iMessage, Discord, and beyond — render reliably:
- Set
og:title,og:description,og:image, andog:urlon every public page. - Use an
og:imageat 1200 × 630 px (JPEG or PNG). Universal safe size. - Include
og:image:widthandog:image:heightdeclarations. Some platforms skip images without dimensions. - Serve everything over HTTPS. Both the page and the image URL.
- Server-render tags. Never inject Open Graph via client-side JavaScript.
- Use absolute URLs. Crawlers don't resolve relative paths.
- Keep redirects short — one hop maximum.
- Set a site-wide default
og:imageso no page ever ships naked. - Test before sharing. See how to test URL unfurl.
Testing Tools
You don't need to send a test message to preview iMessage URL unfurl. TryUnfurl fetches your page live and renders the iMessage preview card — alongside Facebook, LinkedIn, Twitter/X, Slack, Discord, WhatsApp, Teams, and Telegram — from a single URL input. It surfaces every detected Open Graph tag, flags missing values, and catches cross-platform inconsistencies in one view.
For auditing many URLs at once — a launch, a migration, a monthly evergreen sweep — the bulk URL unfurl checker handles up to 100 URLs per run.
Frequently Asked Questions
Why does my iMessage preview show only a URL with no card?
og:title is likely missing from the raw HTML, or iMessage's fetcher couldn't reach your page. Confirm your URL is publicly accessible and that og:title is set in the server-rendered HTML (not injected by JavaScript).
How do I refresh an iMessage link preview?
There is no cache-clearing tool for iMessage. The preview is cached on each recipient's device. To force a fresh preview, the recipient should delete the message and you should resend the link. Or test it yourself by sending the updated URL to a new contact.
Why does my image appear as a small square thumbnail in iMessage instead of a large card?
iOS crops og:image to a square thumbnail in the compact thread view. The full 1200 × 630 image appears when the recipient taps the preview to expand it. For the best compact thumbnail, keep the key visual subject of your image centred so it looks good when square-cropped.
Does iMessage support Twitter Card tags?
No. iMessage only reads Open Graph (og:) tags.
Do Android Messages / RCS previews work the same way?
Android Messages and RCS link previews also read Open Graph tags server-side, but the rendering differs slightly from iMessage. Covering Open Graph fully covers both iMessage on iOS and RCS/Messages on Android.
Why does my preview work in Safari but not in iMessage?
Safari renders your page with full JavaScript execution; iMessage's fetcher does not. If your og: tags are injected by JavaScript, they'll be visible in Safari but invisible to iMessage. Use server-side rendering or static HTML to make them available to all crawlers.
How do I preview URL unfurl on Discord and iMessage at the same time?
TryUnfurl renders the iMessage and Discord cards side-by-side, from the same Open Graph tags both platforms read. It's the fastest way to confirm a URL unfurl is consistent across both apps.
Can I force iMessage to re-fetch a URL without asking the recipient to delete the message?
No. iMessage's preview is locally cached on the recipient's device and cannot be refreshed remotely. Appending a query string (e.g. ?v=2) creates a new URL that iMessage will fetch fresh, which is the closest workaround.