How to Make a Link Preview Show Correctly in Discord
Fix missing or incorrect Discord link previews by checking Open Graph metadata, page access, and viewer settings, then verify the result.
A Discord link preview is generated when someone shares a URL: Discord visits the page and retrieves details such as its title, description, and image. To make a preview show correctly, put accurate Open Graph metadata in the page’s <head>, make both the page and preview image reachable by Discordbot, and check whether the recipient has previews enabled or the sender suppressed the embed. These steps improve the information Discord can retrieve, but do not guarantee a particular card layout. Discord’s link preview documentation says link details are fetched when a link is shared; it does not describe continuous crawling.
1. Add Open Graph metadata to the page
For each public page you want to share, add page-specific metadata inside the HTML document’s <head>. Open Graph defines og:title, og:type, og:image, and og:url as the basic properties. og:description and og:site_name are optional. Discord says it retrieves titles, descriptions, and images, so supply those values accurately.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>API Reference | Example Docs</title>
<meta property="og:type" content="website">
<meta property="og:title" content="API Reference | Example Docs">
<meta property="og:url" content="https://example.com/docs/api">
<meta property="og:image" content="https://example.com/images/api-share.jpg">
<meta property="og:description" content="Reference documentation for the Example API, including authentication and request formats.">
<meta property="og:site_name" content="Example Docs">
</head>
<body>
<h1>API Reference</h1>
</body>
</html>
The sample uses website as a suitable type for an ordinary web page. The URL values are examples: replace them with the canonical URL and a real image URL for the exact page being shared. The Open Graph protocol describes og:description as a one-to-two sentence description; keep it useful and accurate.
| Property | Purpose | What to check |
|---|---|---|
og:title |
Page title in graph metadata | Specific to this page; readable when viewed out of context. |
og:type |
Kind of object | Use an appropriate type, such as website for a normal page. |
og:url |
Canonical object URL | Use the intended public URL, including the correct hostname and path. |
og:image |
Image representing the page | Use a public, absolute URL that serves the intended image without authentication. |
og:description |
Short page summary | Describe this page, not the site generally; one or two sentences is a useful target. |
og:site_name |
Optional site identity | Set it when the broader site name helps identify the page. |
These properties define metadata, not a guaranteed Discord card design. The cited sources do not establish fixed visual positions, precedence rules among metadata formats, or Discord-specific image dimensions and file-size limits for ordinary page previews.
2. Publish and verify the public response
- Open the exact page URL you plan to share. Do not verify only the home page; each route should return its own title, summary, canonical URL, and preview image.
- Inspect the served HTML source and confirm the metadata is in the document head after deployment. If your app renders metadata with JavaScript, check that the initial public response includes it, since Discord’s documented behavior is to visit the shared URL and collect page details.
- Request the page and image from a network that is not logged into your site. Both should be public and not blocked by a login, firewall, or access policy.
- Share the URL in Discord again after the changes are published and inspect the resulting preview. This is a practical check, not a guaranteed cache purge method: Discord’s cited documentation does not specify a cache duration or supported invalidation command.
For a visual check while developing or reviewing a page, ScreenshotNeo captures a rendered page by URL. Its API can show what the page looks like to a browser, but a screenshot alone does not prove which metadata Discord retrieved or whether Discordbot can access the page. Use it alongside source and access checks. See the ScreenshotNeo API documentation.
3. Confirm Discordbot can reach the page
A correct tag cannot help if Discord’s fetch request is blocked. Review server, firewall, CDN, and bot-protection rules for the page and the image. Discord’s documentation gives Discordbot/2.0 as a user-agent example; search logs for Discordbot rather than relying on the entire user-agent string remaining fixed.
A user-agent can be spoofed. If your access policy needs to confirm that a request came from Discord, compare its source IP with Discord’s published public IP ranges and keep the range list current, as Discord advises. Do not allow access based only on a request claiming the Discordbot user-agent.
4. Tell site-side failures apart from display settings
A missing card does not always mean the page metadata is wrong. Check the two viewer and sender controls before changing site code:
- Viewer setting: the recipient may have “Show embeds and link previews” disabled in Discord’s display settings. Ask them to check that setting; Discord’s interface labels or path may change.
- Suppressed link: a sender can put angle brackets around a URL, as in
<https://example.com/docs/api>, to suppress that link’s automatic embed. Remove the brackets if a preview is wanted.
Discord documents both behaviors in its link preview article and support guidance on suppressing previews.
5. Troubleshoot by symptom
| Symptom | Likely cause | Fix |
|---|---|---|
| No preview appears for anyone | Page is blocked or unavailable, or the shared page lacks usable metadata. | Check the exact public URL, deployed HTML head, and page access from outside your logged-in session; inspect server rules for Discordbot requests. |
| Title or description is wrong | The shared route serves stale, generic, or incorrect metadata. | Set page-specific og:title and og:description, deploy, inspect the served response, and share the URL again to observe the result. |
| Image is missing | The image URL is wrong, private, or blocked from the bot. | Use an absolute public og:image URL and verify that it returns the intended image without login or firewall restrictions. |
| Preview works for some people only | Recipients may have disabled previews, or the message may suppress the embed. | Check the recipient’s “Show embeds and link previews” setting and remove angle brackets surrounding the URL. |
| It still shows old information after an update | The observation may reflect previously fetched data or a deployment that did not change the public response. | Verify the live response first, then share again. The cited official material gives no guaranteed cache lifetime or refresh procedure. |
| It works in a browser but not for Discord | Your browser may have cookies or permissions that the bot does not, or server rules may treat the fetch differently. | Test page and image access without a session; review access logs and bot/firewall rules. Do not infer bot reachability from your logged-in browser view. |
6. Keep preview generation reliable
- Maintain metadata per route. Avoid one site-wide title and image for unrelated pages. Check metadata after deployment, especially for dynamically generated pages.
- Keep referenced resources public. The page and image should not require a browser session, an interactive challenge, or a private network.
- Use the canonical URL consistently. Ensure
og:urlidentifies the intended page and matches your canonicalization choices. - Make changes observable. Compare the public response before and after deployment, and keep request logs available when investigating access problems.
- Avoid unsupported assumptions. The primary sources do not specify a preview cache lifetime, a refresh command, exact image constraints, or a fixed card layout. Treat repeated sharing as a check, not a cache-control guarantee.
Or skip the browser setup
For a rendered visual of a page, ScreenshotNeo can return an image with one API request. It is useful for checking the page appearance, while Discord preview metadata and bot access still need the checks above.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com/docs/api -o shot.webp
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://example.com/docs/api"},
timeout=90,
)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({
access_key: 'YOUR_API_KEY',
url: 'https://example.com/docs/api'
});
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await Bun.write('shot.webp', new Uint8Array(await res.arrayBuffer()));
See the API documentation for request options. ScreenshotNeo accepts cookie banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and responses identify page verdict and billing status in headers. Its MCP server lets Claude, Cursor, and other MCP clients take screenshots. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 shots. Sign up for 1,000 free screenshots a month, with no card required.
FAQ
Does Discord continuously crawl my website?
No. Discord says it visits the link when someone shares it in a message.
Can I force Discord to refresh a preview immediately?
The cited Discord documentation does not provide a guaranteed cache invalidation method or cache lifetime. Confirm the live page first and share again as a practical check.
Do Open Graph tags guarantee that a preview will appear?
No. The tags provide page metadata, but the page and image must also be reachable, and viewer settings or sender suppression can prevent display.
What image dimensions does Discord require?
The cited sources do not specify a Discord-specific image dimension requirement for ordinary website link previews.


