diff --git a/src/ui/src/components/core/content/CorePlotlyGraph.def.ts b/src/ui/src/components/core/content/CorePlotlyGraph.def.ts
new file mode 100644
index 00000000..f63eaff2
--- /dev/null
+++ b/src/ui/src/components/core/content/CorePlotlyGraph.def.ts
@@ -0,0 +1,41 @@
+import { FieldType, WriterComponentDefinition } from "@/writerTypes";
+import { cssClasses } from "@/renderer/sharedStyleFields";
+
+const description = "A component that displays Plotly graphs.";
+
+const defaultSpec = {
+ data: [
+ {
+ x: ["a", "b", "c"],
+ y: [22, 25, 29],
+ type: "bar",
+ },
+ ],
+};
+const definition: WriterComponentDefinition = {
+ name: "Plotly Graph",
+ description,
+ category: "Content",
+ fields: {
+ spec: {
+ name: "Graph specification",
+ default: JSON.stringify(defaultSpec, null, 2),
+ desc: "Plotly graph specification. Pass it using state, e.g. @{fig}, or paste a JSON specification.",
+ type: FieldType.Object,
+ },
+ cssClasses,
+ },
+ events: {
+ "plotly-click": {
+ desc: "Sends a list with the clicked points.",
+ },
+ "plotly-selected": {
+ desc: "Sends a list with the selected points.",
+ },
+ "plotly-deselect": {
+ desc: "Triggered when points are deselected.",
+ },
+ },
+};
+
+export default definition;
diff --git a/src/ui/src/components/core/content/CorePlotlyGraph.vue b/src/ui/src/components/core/content/CorePlotlyGraph.vue
index 31557f73..ea23d0bf 100644
--- a/src/ui/src/components/core/content/CorePlotlyGraph.vue
+++ b/src/ui/src/components/core/content/CorePlotlyGraph.vue
@@ -10,49 +10,11 @@ For example, implement cross-filtering.