Docs › Images and media
Link cards
Show an address as a card with title, description and picture (fetchLinkMeta).
Show an address as a box with title, description and picture. Use it to make a source, a product page or a map stand out.
Try it
Click the link card button and enter any address. Pasting an address alone into the text also offers "Show as a card".
Code for this demo
createEditor('#editor', {
toolbar: 'linkCard link | undo redo',
// a real site asks its server (see below)
fetchLinkMeta: async (url) => ({
title: new URL(url).hostname + ' home page',
description: 'What the server read from the page: og:title, og:description and og:image.',
image: 'https://picsum.photos/seed/82/400/240',
}),
});Adding one
- Click Link card (
linkCard) and enter an address; a missinghttps://is added. - Paste an address alone into the text: it goes in as a link, and with
fetchLinkMetaset a message offers "Show as a card", which swaps the link for a card. Kakao Map and Naver Map addresses get the offer even withoutfetchLinkMeta. - Kakao Map and Naver Map addresses in the Map / embed code dialog go in as cards.
fetchLinkMeta: getting the details from your server
Browsers can't read pages on other sites, so your server has to fetch the title and picture. Without fetchLinkMeta, or when it returns null, the card shows only the domain.
createEditor('#editor', {
toolbar: 'board | linkCard',
fetchLinkMeta: async (url) => {
const res = await fetch('/api/link-meta?url=' + encodeURIComponent(url));
return res.ok ? res.json() : null; // { title, description?, image?, siteName? }
},
});// Node example: read the page's og: tags
app.get('/api/link-meta', async (req, res) => {
const url = new URL(req.query.url);
if (!/^https?:$/.test(url.protocol)) return res.status(400).end();
const html = await (await fetch(url, { redirect: 'follow' })).text();
const og = (p) => html.match(new RegExp('<meta[^>]+property=["\']og:' + p + '["\'][^>]+content=["\']([^"\']*)', 'i'))?.[1];
res.json({
title: og('title') ?? html.match(/<title>([^<]*)/i)?.[1] ?? url.hostname,
description: og('description'),
image: og('image'),
siteName: og('site_name'),
});
});Saved HTML
<div data-link-card="" style="margin: 0.8em 0">
<a href="https://…" target="_blank" rel="noopener noreferrer" style="display: flex; gap: 14px; …">
<img src="https://…/og.jpg" alt="" style="width: 120px; height: 90px; object-fit: cover; …">
<span style="display: block; min-width: 0">
<strong style="display: block">Title</strong>
<span style="…">Description</span>
<span style="…">Site name</span>
</span>
</a>
</div>Titles are cut at 120 characters and descriptions at 160. The picture is used only for http(s) addresses; without a site name the domain shows. Cards open in a new tab, and in the editor a card is one piece.
Where it is
linkCard is in the ⋯ more menu of the board and full presets.
Options
| Name | Type | Default | Description |
|---|---|---|---|
linkCard | toolbar item | Opens the dialog that makes a card from an address. | |
fetchLinkMeta | (url) => Promise<LinkMeta | null> | Gets title, description and picture from your server; when set, pasted addresses offer a card. | |
LinkMeta.title | string | Card title; the domain when empty. | |
LinkMeta.description | string | Description (up to 160 characters). | |
LinkMeta.image | string | Picture address (http/https). | |
LinkMeta.siteName | string | Small text at the bottom; the domain when empty. |