diff --git a/src/renderer/renderElement.ts b/src/renderer/renderElement.ts
index 126d6677..6db858d9 100644
--- a/src/renderer/renderElement.ts
+++ b/src/renderer/renderElement.ts
@@ -836,6 +836,18 @@ export const renderElementToSvg = (
const cy = (y2 - y1) / 2 - (element.y - y1);
const degree = (180 * element.angle) / Math.PI;
const generator = rsvg.generator;
+
+ // element to append node to, most of the time svgRoot
+ let root = svgRoot;
+
+ // if the element has a link, create an anchor tag and make that the new root
+ if (element.link) {
+ const anchorTag = svgRoot.ownerDocument!.createElementNS(SVG_NS, "a");
+ anchorTag.setAttribute("href", element.link);
+ root.appendChild(anchorTag);
+ root = anchorTag;
+ }
+
switch (element.type) {
case "selection": {
// Since this is used only during editing experience, which is canvas based,
@@ -863,7 +875,7 @@ export const renderElementToSvg = (
offsetY || 0
}) rotate(${degree} ${cx} ${cy})`,
);
- svgRoot.appendChild(node);
+ root.appendChild(node);
break;
}
case "line":
@@ -898,7 +910,7 @@ export const renderElementToSvg = (
}
group.appendChild(node);
});
- svgRoot.appendChild(group);
+ root.appendChild(group);
break;
}
case "freedraw": {
@@ -923,7 +935,7 @@ export const renderElementToSvg = (
path.setAttribute("fill", element.strokeColor);
path.setAttribute("d", getFreeDrawSvgPath(element));
node.appendChild(path);
- svgRoot.appendChild(node);
+ root.appendChild(node);
break;
}
case "image": {
@@ -944,7 +956,7 @@ export const renderElementToSvg = (
symbol.appendChild(image);
- svgRoot.prepend(symbol);
+ root.prepend(symbol);
}
const use = svgRoot.ownerDocument!.createElementNS(SVG_NS, "use");
@@ -965,7 +977,7 @@ export const renderElementToSvg = (
}) rotate(${degree} ${cx} ${cy})`,
);
- svgRoot.appendChild(use);
+ root.appendChild(use);
}
break;
}
@@ -1012,7 +1024,7 @@ export const renderElementToSvg = (
text.setAttribute("direction", direction);
node.appendChild(text);
}
- svgRoot.appendChild(node);
+ root.appendChild(node);
} else {
// @ts-ignore
throw new Error(`Unimplemented type ${element.type}`);
diff --git a/src/tests/fixtures/elementFixture.ts b/src/tests/fixtures/elementFixture.ts
index 0b84d0af..eca71256 100644
--- a/src/tests/fixtures/elementFixture.ts
+++ b/src/tests/fixtures/elementFixture.ts
@@ -37,3 +37,8 @@ export const diamondFixture: ExcalidrawElement = {
...elementBase,
type: "diamond",
};
+export const rectangleWithLinkFixture: ExcalidrawElement = {
+ ...elementBase,
+ type: "rectangle",
+ link: "excalidraw.com",
+};
diff --git a/src/tests/scene/__snapshots__/export.test.ts.snap b/src/tests/scene/__snapshots__/export.test.ts.snap
index c75f2b2f..c0290f75 100644
--- a/src/tests/scene/__snapshots__/export.test.ts.snap
+++ b/src/tests/scene/__snapshots__/export.test.ts.snap
@@ -71,6 +71,25 @@ exports[`exportToSvg with default arguments 1`] = `
`;
+exports[`exportToSvg with elements that have a link 1`] = `
+"
+
+
+
+
+
+ "
+`;
+
exports[`exportToSvg with exportEmbedScene 1`] = `
"
diff --git a/src/tests/scene/export.test.ts b/src/tests/scene/export.test.ts
index 3267c911..1b6f7211 100644
--- a/src/tests/scene/export.test.ts
+++ b/src/tests/scene/export.test.ts
@@ -1,6 +1,10 @@
import { NonDeletedExcalidrawElement } from "../../element/types";
import * as exportUtils from "../../scene/export";
-import { diamondFixture, ellipseFixture } from "../fixtures/elementFixture";
+import {
+ diamondFixture,
+ ellipseFixture,
+ rectangleWithLinkFixture,
+} from "../fixtures/elementFixture";
describe("exportToSvg", () => {
const ELEMENT_HEIGHT = 100;
@@ -112,4 +116,13 @@ describe("exportToSvg", () => {
);
expect(svgElement.innerHTML).toMatchSnapshot();
});
+
+ it("with elements that have a link", async () => {
+ const svgElement = await exportUtils.exportToSvg(
+ [rectangleWithLinkFixture],
+ DEFAULT_OPTIONS,
+ null,
+ );
+ expect(svgElement.innerHTML).toMatchSnapshot();
+ });
});