diff --git a/snippets/components/integrators/embeds/DataEmbed.jsx b/snippets/components/integrators/embeds/DataEmbed.jsx index a5beed083..0b443315b 100644 --- a/snippets/components/integrators/embeds/DataEmbed.jsx +++ b/snippets/components/integrators/embeds/DataEmbed.jsx @@ -93,6 +93,22 @@ export const MarkdownEmbed = ({ url, className = '', style = {}, ...rest }) => { const [html, setHtml] = useState('') useEffect(() => { + // Derive base URL so relative image paths in the remote file can be resolved + const lastSlash = url.lastIndexOf('/') + const baseUrl = lastSlash >= 0 ? url.substring(0, lastSlash + 1) : '' + const origin = baseUrl.match(/^(https?:\/\/[^/]+)/)?.[1] ?? '' + + const resolveUrl = (src) => { + // Pass through absolute URLs, protocol-relative, data URIs, and fragment links + if (/^https?:\/\//i.test(src) || src.startsWith('//') || src.startsWith('data:') || src.startsWith('#')) return src + // Root-relative paths anchor to the origin, not the directory base + if (src.startsWith('/')) return origin + src + return baseUrl + src + } + + const escapeAttr = (str) => + String(str).replace(/&/g, '&').replace(/"/g, '"').replace(//g, '>') + fetch(url) .then((res) => res.text()) .then((md) => { @@ -102,10 +118,20 @@ export const MarkdownEmbed = ({ url, className = '', style = {}, ...rest }) => { .replace(/```(\w*)\n([\s\S]*?)```/g, '
$2')
// Inline code
.replace(/`([^`]+)`/g, '$1')
- // Images
+ // Markdown images — resolve relative src to absolute
.replace(
/!\[([^\]]*)\]\(([^)]+)\)/g,
- '