diff --git a/packages/components/src/components/code-block/code-block.stories.tsx b/packages/components/src/components/code-block/code-block.stories.tsx
index b7dc7ca..418e510 100644
--- a/packages/components/src/components/code-block/code-block.stories.tsx
+++ b/packages/components/src/components/code-block/code-block.stories.tsx
@@ -464,3 +464,52 @@ export const WithCustomClassName: Story = {
),
};
+export const TemplateLiteralSimple: Story = {
+ render: () => (
+
+ {`
+ echo hello
+ echo world
+ echo storybook
+ `}
+
+ ),
+};
+export const TemplateLiteralYaml: Story = {
+ render: () => (
+
+ {`
+ applications:
+ myapp:
+ source:
+ root: "/"
+ `}
+
+ ),
+};
+export const TemplateLiteralJavascript: Story = {
+ render: () => (
+
+ {`
+ function greet(name) {
+ console.log("Hello " + name);
+ }
+
+ greet("Mintlify");
+ `}
+
+ ),
+};
+export const TemplateLiteralWithEmptyLines: Story = {
+ render: () => (
+
+ {`
+
+ npm install
+
+ npm run build
+
+ `}
+
+ ),
+};
diff --git a/packages/components/src/components/code-block/code-block.tsx b/packages/components/src/components/code-block/code-block.tsx
index 61ac677..0f899cf 100644
--- a/packages/components/src/components/code-block/code-block.tsx
+++ b/packages/components/src/components/code-block/code-block.tsx
@@ -2,6 +2,7 @@ import type { ReactNode, RefObject } from "react";
import { Classes } from "@/constants/selectors";
import { cn } from "@/utils/cn";
+import { dedent } from "@/utils/dedent";
import { getNodeText } from "@/utils/get-node-text";
import type { CodeBlockTheme, CodeStyling } from "@/utils/shiki/code-styling";
@@ -98,7 +99,12 @@ const CodeBlock = function CodeBlock(params: CodeBlockProps) {
copyButtonProps,
} = params;
- const codeString = getNodeText(children);
+ let codeString = getNodeText(children);
+
+ if (typeof codeString === "string") {
+ codeString = dedent(codeString);
+ }
+
const hasGrayBackgroundContainer = !!filename || !!icon;
return (
@@ -146,13 +152,16 @@ const CodeBlock = function CodeBlock(params: CodeBlockProps) {
{askAiButton && askAiButton}
)}
+
+ >
+ {codeString}
+
);
};
diff --git a/packages/components/src/utils/dedent.ts b/packages/components/src/utils/dedent.ts
new file mode 100644
index 0000000..7311d48
--- /dev/null
+++ b/packages/components/src/utils/dedent.ts
@@ -0,0 +1,25 @@
+const INDENT_REGEX = /^[ ]*/;
+
+export function dedent(code: string): string {
+ const lines = code.split("\n");
+
+ while (lines.length && lines[0].trim() === "") {
+ lines.shift();
+ }
+
+ while (lines.length && lines.at(-1)?.trim() === "") {
+ lines.pop();
+ }
+
+ if (lines.length === 0) {
+ return "";
+ }
+
+ const indents = lines
+ .filter((line) => line.trim().length > 0)
+ .map((line) => line.match(INDENT_REGEX)?.[0].length ?? 0);
+
+ const minIndent = Math.min(...indents);
+
+ return lines.map((line) => line.slice(minIndent)).join("\n");
+}
\ No newline at end of file