FumaDocs React Component to Display Code from Github Repos
The GithubCodeBlock component allows you to embed and display code from GitHub repositories directly in your Fuma Docs application. It supports line extraction, syntax highlighting, and line highlighting features. Installation You need to have fumadocs setup ready and running Step 1: Copy following code anywhere into your components import * as Base from "fumadocs-ui/components/codeblock"; import { highlight } from "fumadocs-core/highlight"; import { transformerMetaHighlight } from "@shikijs/transformers"; // Types export interface CodeBlockProps { code: string; wrapper?: Base.CodeBlockProps; lang: string; highlightLines?: string; } interface GithubCodeBlockProps { url: string; extractLines?: boolean; highlightLines?: string; wrapper?: Base.CodeBlockProps; } interface GitHubReference { rawUrl: string; fromLine?: number; toLine?: number; highlightLines?: string; } // Helper functions function formatHighlightLines(highlightLines?: string): string | undefined { if (!highlightLines) return undefined; return highlightLines.startsWith("{") && highlightLines.endsWith("}") ? highlightLines : `{${highlightLines}}`; } function getLanguageFromUrl(url: string): string { try { return url.split(".").pop()?.toLowerCase() || ""; } catch { return ""; } } function parseGitHubUrl(url: string): GitHubReference { try { // Split the URL to separate the line reference part const [githubUrl, loc] = url.split("#"); if (!githubUrl) { throw new Error("Invalid GitHub URL"); } // Initialize line reference variables let fromLine: number | undefined; let toLine: number | undefined; let highlightLines: string | undefined; // Parse line references if present if (loc) { const lineParts = loc.split("-"); if (lineParts[0]?.startsWith("L")) { fromLine = parseInt(lineParts[0].slice(1), 10) - 1; if (lineParts[1]?.startsWith("L")) { toLine = parseInt(lineParts[1].slice(1), 10) - 1; } else { toLine = fromLine; } // Always generate highlight lines from location // These will be used if no explicit highlightLines prop is provided if (fromLine !== undefined && toLine !== undefined) { const startLine = fromLine + 1; const endLine = toLine + 1; highlightLines = startLine === endLine ? `{${startLine}}` : `{${startLine}-${endLine}}`; } } } // Parse GitHub URL to create raw URL const urlObj = new URL(githubUrl); const pathParts = urlObj.pathname.split("/").slice(1); if (pathParts.length { if (line.length === 0) return indent; const spaces = line.match(/^\s+/); return spaces ? Math.min(indent, spaces[0].length) : 0; }, Infinity ); // Remove common indentation and join lines return selectedLines .map((line) => { if (line.length === 0) return line; return line.slice(commonIndent lines from URL loc const formattedHighlightLines = formatHighlightLines( highlightLines || reference.highlightLines ); // Fetch the code content, extracting specific lines if needed const code = await fetchCode( reference.rawUrl, extractLines ? reference.fromLine : undefined, extractLines ? reference.toLine : undefined ); const lang = getLanguageFromUrl(reference.rawUrl); return ( ); } catch (error) { console.error("Error in GithubCodeBlock:", error); return ( ); } } Step 2: Add to MDX Components import defaultMdxComponents from "fumadocs-ui/mdx"; import type { MDXComponents } from "mdx/types"; import GithubCodeBlock from "./components/github-code-block"; export function getMDXComponents(components?: MDXComponents): MDXComponents { return { ...defaultMdxComponents, GithubCodeBlock: GithubCodeBlock, ...components, }; } Basic Usage Props The component accepts the following props: Prop Type Default Description url string (required) GitHub URL to the file you want to display extractLines boolean false Whether to extract specific lines from the file highlightLines string undefined Lines to highlight in the format "{1,3-4}" wrapper object undefined CodeBlockProps to pass to the underlying CodeBlock component Examples Display a Complete File Extract Specific Lines You can extract specific lines from a file by adding a line reference to the URL and setting extractLines to true: Highlight Specific Lines You can highlight specific lines using the highlightLines prop: Launch Post // Detect dark theme var iframe = document.getElementById('tweet-1912033485285376492-240'); if (document.body.className.includes('dark-theme')) {

The GithubCodeBlock component allows you to embed and display code from GitHub repositories directly in your Fuma Docs application. It supports line extraction, syntax highlighting, and line highlighting features.
Installation
You need to have fumadocs setup ready and running
Step 1: Copy following code anywhere into your components
import * as Base from "fumadocs-ui/components/codeblock";
import { highlight } from "fumadocs-core/highlight";
import { transformerMetaHighlight } from "@shikijs/transformers";
// Types
export interface CodeBlockProps {
code: string;
wrapper?: Base.CodeBlockProps;
lang: string;
highlightLines?: string;
}
interface GithubCodeBlockProps {
url: string;
extractLines?: boolean;
highlightLines?: string;
wrapper?: Base.CodeBlockProps;
}
interface GitHubReference {
rawUrl: string;
fromLine?: number;
toLine?: number;
highlightLines?: string;
}
// Helper functions
function formatHighlightLines(highlightLines?: string): string | undefined {
if (!highlightLines) return undefined;
return highlightLines.startsWith("{") && highlightLines.endsWith("}")
? highlightLines
: `{${highlightLines}}`;
}
function getLanguageFromUrl(url: string): string {
try {
return url.split(".").pop()?.toLowerCase() || "";
} catch {
return "";
}
}
function parseGitHubUrl(url: string): GitHubReference {
try {
// Split the URL to separate the line reference part
const [githubUrl, loc] = url.split("#");
if (!githubUrl) {
throw new Error("Invalid GitHub URL");
}
// Initialize line reference variables
let fromLine: number | undefined;
let toLine: number | undefined;
let highlightLines: string | undefined;
// Parse line references if present
if (loc) {
const lineParts = loc.split("-");
if (lineParts[0]?.startsWith("L")) {
fromLine = parseInt(lineParts[0].slice(1), 10) - 1;
if (lineParts[1]?.startsWith("L")) {
toLine = parseInt(lineParts[1].slice(1), 10) - 1;
} else {
toLine = fromLine;
}
// Always generate highlight lines from location
// These will be used if no explicit highlightLines prop is provided
if (fromLine !== undefined && toLine !== undefined) {
const startLine = fromLine + 1;
const endLine = toLine + 1;
highlightLines =
startLine === endLine
? `{${startLine}}`
: `{${startLine}-${endLine}}`;
}
}
}
// Parse GitHub URL to create raw URL
const urlObj = new URL(githubUrl);
const pathParts = urlObj.pathname.split("/").slice(1);
if (pathParts.length < 5) {
throw new Error("Invalid GitHub repository path");
}
const [org, repo, _, branch, ...pathSeg] = pathParts;
if (!org || !repo || !branch || pathSeg.length === 0) {
throw new Error("Missing required GitHub path components");
}
// Create reference object with raw URL and line info
return {
rawUrl: `https://raw.githubusercontent.com/${org}/${repo}/${branch}/${pathSeg.join("/")}`,
fromLine,
toLine,
highlightLines,
};
} catch (error) {
console.error("Error parsing GitHub URL:", error);
throw new Error(
`Invalid GitHub URL: ${error instanceof Error ? error.message : String(error)}`
);
}
}
async function fetchCode(url: string, fromLine?: number, toLine?: number) {
try {
const response = await fetch(url, { cache: "force-cache" });
if (!response.ok) {
throw new Error(
`Failed to fetch code: ${response.status} ${response.statusText}`
);
}
const content = await response.text();
// Return full content if no line numbers are specified
if (fromLine === undefined || toLine === undefined) {
return content;
}
// Extract specific lines
const lines = content.split("\n");
const selectedLines = lines.slice(fromLine, toLine + 1);
if (selectedLines.length === 0) {
return content;
}
// Calculate common indentation to remove
const commonIndent = selectedLines.reduce(
(indent: number, line: string) => {
if (line.length === 0) return indent;
const spaces = line.match(/^\s+/);
return spaces ? Math.min(indent, spaces[0].length) : 0;
},
Infinity
);
// Remove common indentation and join lines
return selectedLines
.map((line) => {
if (line.length === 0) return line;
return line.slice(commonIndent < Infinity ? commonIndent : 0);
})
.join("\n");
} catch (error) {
console.error("Error fetching code:", error);
return `// Error fetching code: ${error instanceof Error ? error.message : String(error)}`;
}
}
// Components
export async function CodeBlock({
code,
lang,
wrapper,
highlightLines,
}: CodeBlockProps) {
const rendered = await highlight(code, {
lang,
meta: highlightLines ? { __raw: highlightLines } : undefined,
themes: {
light: "github-light",
dark: "github-dark",
},
components: {
pre: Base.Pre,
},
transformers: [transformerMetaHighlight()],
});
return <Base.CodeBlock {...wrapper}>{rendered}Base.CodeBlock>;
}
export default async function GithubCodeBlock({
url,
extractLines = false,
highlightLines,
wrapper,
}: GithubCodeBlockProps) {
try {
// Validate GitHub URL
if (!url.includes("github.com")) {
throw new Error("This component only supports GitHub URLs");
}
// Parse GitHub URL to get raw URL and line info
const reference = parseGitHubUrl(url);
// Format highlight lines for Shiki
// Priority: explicitly provided highlightLines prop > lines from URL loc
const formattedHighlightLines = formatHighlightLines(
highlightLines || reference.highlightLines
);
// Fetch the code content, extracting specific lines if needed
const code = await fetchCode(
reference.rawUrl,
extractLines ? reference.fromLine : undefined,
extractLines ? reference.toLine : undefined
);
const lang = getLanguageFromUrl(reference.rawUrl);
return (
<CodeBlock
lang={lang}
code={code}
highlightLines={formattedHighlightLines}
wrapper={wrapper}
/>
);
} catch (error) {
console.error("Error in GithubCodeBlock:", error);
return (
<CodeBlock
lang="text"
code={`// Error: ${error instanceof Error ? error.message : String(error)}`}
wrapper={wrapper}
/>
);
}
}
Step 2: Add to MDX Components
import defaultMdxComponents from "fumadocs-ui/mdx";
import type { MDXComponents } from "mdx/types";
import GithubCodeBlock from "./components/github-code-block";
export function getMDXComponents(components?: MDXComponents): MDXComponents {
return {
...defaultMdxComponents,
GithubCodeBlock: GithubCodeBlock,
...components,
};
}
Basic Usage
<GithubCodeBlock url="https://github.com/rjvim/react-component-library-starter/blob/main/lerna.json" />
Props
The component accepts the following props:
Prop | Type | Default | Description |
---|---|---|---|
url |
string |
(required) | GitHub URL to the file you want to display |
extractLines |
boolean |
false |
Whether to extract specific lines from the file |
highlightLines |
string |
undefined |
Lines to highlight in the format "{1,3-4}"
|
wrapper |
object |
undefined |
CodeBlockProps to pass to the underlying CodeBlock component |
Examples
Display a Complete File
<GithubCodeBlock url="https://github.com/rjvim/react-component-library-starter/blob/main/lerna.json" />
Extract Specific Lines
You can extract specific lines from a file by adding a line reference to the URL and setting extractLines
to true
:
<GithubCodeBlock
url="https://github.com/rjvim/react-component-library-starter/blob/main/lerna.json#L2-L4"
extractLines={true}
/>
Highlight Specific Lines
You can highlight specific lines using the highlightLines
prop:
<GithubCodeBlock
url="https://github.com/rjvim/react-component-library-starter/blob/main/lerna.json"
highlightLines="{2,4}"
/>
Launch Post
// Detect dark theme var iframe = document.getElementById('tweet-1912033485285376492-240'); if (document.body.className.includes('dark-theme')) { iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1912033485285376492&theme=dark" }
Note: In dev.to to editor I am not able to show the output of using the component, you can check that on: https://rjv.im/blog/solution/github-code-block