diff --git a/public/images/plantuml.png b/public/images/plantuml.png
new file mode 100644
index 0000000000..5ce86ff9af
Binary files /dev/null and b/public/images/plantuml.png differ
diff --git a/shared/editor/embeds/PlantUml.tsx b/shared/editor/embeds/PlantUml.tsx
new file mode 100644
index 0000000000..ff9cdc523b
--- /dev/null
+++ b/shared/editor/embeds/PlantUml.tsx
@@ -0,0 +1,31 @@
+import * as React from "react";
+import Frame from "../components/Frame";
+import Image from "../components/Img";
+import { EmbedProps as Props } from ".";
+import { useTheme } from "styled-components";
+
+function PlantUmlDiagrams({ matches, ...props }: Props) {
+ const theme = useTheme();
+ const mode = theme.isDark ? "dsvg" : "svg";
+ const title = props.attrs.href.split("/uml/")[1];
+ const finalUrl = `https://www.plantuml.com/plantuml/${mode}/${title}`;
+
+ return (
+
+ }
+ canonicalUrl={props.attrs.href}
+ border
+ />
+ );
+}
+
+export default PlantUmlDiagrams;
diff --git a/shared/editor/embeds/index.tsx b/shared/editor/embeds/index.tsx
index d2d2f453fc..9b72e6b1c7 100644
--- a/shared/editor/embeds/index.tsx
+++ b/shared/editor/embeds/index.tsx
@@ -20,6 +20,7 @@ import Spotify from "./Spotify";
import Trello from "./Trello";
import Vimeo from "./Vimeo";
import YouTube from "./YouTube";
+import PlantUmlDiagrams from "./PlantUml";
export type EmbedProps = {
isSelected: boolean;
@@ -677,6 +678,15 @@ const embeds: EmbedDescriptor[] = [
icon:
,
component: YouTube,
}),
+ new EmbedDescriptor({
+ title: "Plant UML",
+ keywords: "plant plantuml uml",
+ regexMatch: [
+ /(?:https?:\/\/)?(?:www\.)?editor\.plantuml\.com\/uml\/([a-zA-Z0-9\-_]+)([\&\?].*)?$/i,
+ ],
+ icon:
,
+ component: PlantUmlDiagrams,
+ }),
/* The generic iframe embed should always be the last one */
new EmbedDescriptor({
title: "Embed",