The short version
- A Slack link preview image is the picture Slack shows under a pasted link, taken from og:image, not uploaded in Slack.
- Slackbot-LinkExpanding reads oEmbed, Twitter Card and Open Graph tags from the start of the HTML, then fetches the image to check it.
- Slack publishes no image size or crop box. Use a 1200×630 PNG or JPEG at an absolute https URL, with the headline in the centre.
- Slack caches each URL for around 30 minutes, and will not expand the same link again in one conversation within an hour.
- A bare URL usually means missing tags, a relative or private image, no protocol, more than five links, or previews switched off.
On this page
A Slack link preview image is the picture on the card Slack adds when someone pastes your URL. In a customer channel, a launch thread or an investor's workspace, that card is the first look at the product, and a missing picture leaves a bare link. You do not upload the image to Slack. Slack fetches the page, reads the preview tags, and downloads the file those tags name.
What Slack draws when you paste a link
For an ordinary website this is classic link unfurling. If no Slack app is registered for your domain, Slack crawls the URL, reads Open Graph and Twitter Card metadata, and draws a small stand-in for the page: site name, title, a short description, and the image when the tags supply one.
The user agent is Slackbot-LinkExpanding 1.0 (+https://. Slack fetches as little of the page as it can, via HTTP Range headers, looking for oEmbed, Twitter Card and Open Graph tags, then fetches the image to check it. That page fetch is cached globally for around 30 minutes. Images in the channel are served through Slack-ImgProxy over HTTPS.
A Slack app can replace the card, but only for domains it has registered. That is app unfurling, a feature you build, not a tag on the marketing site. Unless you have shipped that app, classic unfurling is what you get. The URL must include a protocol. Slack will not unfurl a bare domain such as keel.example/.
The tags that put a picture on the card
og:site_name is the brand line, og:title the headline, og:description the sentence, and og:image the picture. Add width, height and alt text, and set twitter:card to summary_large_image so the same page still asks for a large card on X. Slack reads both sets of tags. The wider set is in Open Graph tags.
<meta property="og:site_name" content="Keel" />
<meta property="og:title" content="Billing, simplified" />
<meta property="og:description" content="How Keel handles seats, invoices and the API." />
<meta property="og:image" content="https://keel.example/og/billing-v2.png" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
<meta property="og:image:alt" content="Billing, simplified, on a gradient" />
<meta property="og:url" content="https://keel.example/billing" />
<meta name="twitter:card" content="summary_large_image" />The image address must start with https://. The robot does not resolve / against your domain. The tags must already be in the HTML the server sends: a ranged fetch does not run JavaScript, so tags added after load are invisible. Read the page source, not the inspector.
If the site publishes oEmbed, check it too. Slack looks for oEmbed as well as Open Graph, so rule out a stale thumbnail there. The image URL must open as the image in a private window, not a sign-in page. A favicon is not this file. If the picture is missing on every network, use OG image not showing.
Where the picture survives being shown small
Slack publishes no width, height or crop rectangle. Any exact Slack crop you have seen quoted is someone's measurement, not a spec. Put a 1200×630 file in og:image, about 1.91 to 1. LinkedIn's link image is 1200×627, close enough that one file serves both. OG image size covers the other networks. Use PNG for type and flat colour, JPEG for a photograph: PNG versus JPEG.
In a channel the image is far smaller than 1200 pixels wide. Slack publishes no crop, so treat the edges as unsafe: one short line, large, in the centre, with about 60 pixels clear inside each edge. That margin is yours, not a Slack rule. A screenshot of the product fails here, because at chat size the interface turns into noise.
Leave out
Use it for
Leave out
Use it for
Leave out
Use it for
Leave out
Too many points for a card that is shown small.
One line, the product name above it, edges clear.
Let the tags name the page and the image carry recognition. 'How Keel bills annual seats' belongs in og:title. The picture needs the product name and three or four words, not a second copy of the title in type that is too small.
- Home. Product name and what it does: 'Billing for B2B teams', not a slogan the channel has never heard.
- A docs page. The task, such as 'Invite a teammate'. The docs name is already in
og:site_name. - A changelog. The change, such as 'Annual seats', not the word Changelog. Put the date in the description.
On a gradient, put the line on the calmest area and check it when you squint. Text on a gradient is the method. The card has no room for a box behind the words.
Why the link stays bare
Most bare Slack links fail before the artwork matters. Fix the fetch first.
Avoid
- A relative path such as /og/billing.png
- Tags added by JavaScript after load
- A screenshot of the whole app
- Overwriting og.png, then pasting the same URL
- Five or more links in one message
Do
- An absolute https URL to a 1200×630 PNG
- Tags in the HTML the server sends
- One short line in the centre
- A new filename when the picture changes
- A single link while you test
Some failures are on the Slack side. A private page never previews. Previews may be off under Preferences, then Messages and media, or an admin may have restricted app previews. If that link was already shared in the conversation within the past hour, Slack will not expand it again, so a second paste in the same thread is a bad test.
Check the card, then force a new fetch
- 1
Read the HTML the robot reads
View source on the live URL. Confirm the four
og:tags are in the head, and thatog:imageis a full https address. - 2
Open the image on its own
Load the image URL in a private window. You want the picture, not a sign-in page.
- 3
Draw the 1200×630 card
One line in the centre, the product name small above it, edges clear. PNG for flat colour and type, JPEG for a photo.
- 4
Paste a single https URL
One link, protocol included, in a channel where previews are on. More than five links and nothing expands.
- 5
Change the address if it sticks
Use a new image filename. Slack caches a URL for around 30 minutes, and will not expand that link again in the same conversation within the hour. An admin can check the metadata in Slack's unfurl debugger.
For a card on every docs page, generate it from the title instead of drawing each one by hand. Dynamic OG images is that system, and link preview image covers the same card outside Slack. The picture should still match the product, which is the point of SaaS branding.
In Gradiently the link preview size is already 1200×630, so the export matches the file you name in og:image. The Mark is the background, and Auto ink picks light or dark type from that Mark so the line stays readable when the card is small. Explore shows the same Mark as a Slack unfurl: a preview of the card, not an editable design.
Questions people ask
What size should a Slack link preview image be?
Slack publishes no pixel size. Use 1200×630, the Open Graph link preview, as a PNG or JPEG at an absolute https URL, with the headline in the centre.
Why does my link look bare in Slack?
Usually the tags are missing, the image address is relative or behind a login, the URL has no https://, or the message has more than five links. Previews may also be off under Preferences, then Messages and media.
How do I refresh a Slack unfurl after changing the image?
Give the image a new filename and update og:image. Slack caches each URL for around 30 minutes, and will not expand the same link again in a conversation within the past hour.
Does Slack read Open Graph tags?
Yes. Classic unfurling reads Open Graph and Twitter Card tags, and the link-expanding robot also looks for oEmbed. The tags must be in the HTML the server sends.
Why did the preview show once and not the second time?
If the same link was shared in that conversation within the past hour, Slack does not expand it again. Try another conversation, and use a new image filename if the picture changed.
Written by Gradiently
The team behind Gradiently, a design tool built around Marks: living gradients that make everything you design look like yours.
See our profile