Skip to content

Instantly share code, notes, and snippets.

@codemile
Created January 2, 2025 16:58
Show Gist options
  • Save codemile/68c0b1998cf90af8a2fc1c7960bdcc6e to your computer and use it in GitHub Desktop.
Save codemile/68c0b1998cf90af8a2fc1c7960bdcc6e to your computer and use it in GitHub Desktop.
React component for syntax highlighting using Prism.js with support for multiple languages and a custom theme
import classNames from 'classnames';
import Prism from 'prismjs';
import {FC, useEffect, useMemo, useRef} from 'react';
import {ClassNameProps} from '../utils/withClassName';
import 'prismjs';
import 'prismjs/themes/prism-solarizedlight.css';
import 'prismjs/components/prism-shell-session';
import 'prismjs/components/prism-graphql';
import 'prismjs/components/prism-json';
import 'prismjs/components/prism-turtle';
function escapeHtml(unsafe) {
return unsafe
.replace(/&/g, '&')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#039;');
}
interface SourceCodeProps {
language: string;
source: string;
}
export const SourceCode: FC<SourceCodeProps & ClassNameProps> = ({
language,
source,
className
}) => {
const ref = useRef<HTMLPreElement>(null);
useEffect(() => {
if (ref.current) {
Prism.highlightElement(ref.current);
}
}, [source]);
const __html = useMemo(() => {
return `<code>${escapeHtml(source)}</code>`;
}, [source]);
return (
<pre
ref={ref}
className={classNames(
'border rounded p-3 font-mono overflow-auto',
className,
language
)}
dangerouslySetInnerHTML={{__html}}
/>
);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment