+
+ {[['Bold','**','**'],['Italic','*','*'],['Code','`','`'],['Link','[','](https://example.com)'],['H2','## ','']].map(([label, before, after]) => )}
+
+
+
+
+
+
+
+
+
+ {words} words{chars} chars{lines} lines{readingMinutes} min readHTML is sanitized before rendering and export
+ ;
+}
diff --git a/app/(tools)/markdown-preview/opengraph-image.tsx b/app/(tools)/markdown-preview/opengraph-image.tsx
new file mode 100644
index 0000000..8338d41
--- /dev/null
+++ b/app/(tools)/markdown-preview/opengraph-image.tsx
@@ -0,0 +1,11 @@
+import { getTool } from "@/lib/tools";
+import { renderToolOgImage, OG_SIZE, OG_CONTENT_TYPE } from "@/lib/og";
+
+const tool = getTool("markdown-preview")!;
+export const alt = tool.ogTitle;
+export const size = OG_SIZE;
+export const contentType = OG_CONTENT_TYPE;
+
+export default function OpenGraphImage() {
+ return renderToolOgImage(tool);
+}
diff --git a/app/(tools)/markdown-preview/page.tsx b/app/(tools)/markdown-preview/page.tsx
new file mode 100644
index 0000000..529186a
--- /dev/null
+++ b/app/(tools)/markdown-preview/page.tsx
@@ -0,0 +1,12 @@
+import type { Metadata } from "next";
+import { ToolPageLayout } from "@/components/shared/ToolPageLayout";
+import { generateToolMetadata } from "@/lib/toolMetadata";
+import { getTool } from "@/lib/tools";
+import { MarkdownPreviewClient } from "./MarkdownPreviewClient";
+
+const tool = getTool("markdown-preview")!;
+export const metadata: Metadata = generateToolMetadata(tool);
+
+export default function MarkdownPreviewPage() {
+ return