Prismjs is a lightweight, extensible syntax highlighter that supports hundreds of languages. You can use it to render syntax highlighted code blocks with broad language coverage.
Prismjs Highlighter
export default function Page() {
return <h1>Hello</h1>
}Installation
shadcn/ui
shadcn/ui Command
pnpm dlx shadcn@latest add https://code-blocks.pheralb.dev/r/prismjs-highlighter.jsonManual
- Install the following dependencies:
Prismjs Dependencies
pnpm i prismjsand the types for TypeScript support:
Prismjs Types
pnpm i @types/prismjs -D- Create your Prismjs utility file:
prismjs-highlighter
import Prism from "prismjs";
// Languages
import "prismjs/components/prism-typescript";
import "prismjs/components/prism-jsx";
import "prismjs/components/prism-tsx";
import "prismjs/components/prism-bash";
import "prismjs/components/prism-json";
import "prismjs/components/prism-css";
import "prismjs/components/prism-markdown";
type Languages =
| "typescript"
| "tsx"
| "jsx"
| "bash"
| "json"
| "css"
| "markdown";
interface Highlighter {
code: string;
language?: Languages;
}
const highlight = ({ code, language = "typescript" }: Highlighter) => {
const grammar = Prism.languages[language];
const html = grammar ? Prism.highlight(code, grammar, language) : code;
return html
.split("\n")
.map((line) => `<span class="prism__line">${line}</span>`)
.join("\n");
};
export { highlight, type Languages };Styles
This CSS file includes light/dark mode styles and token colors. You can customize it as needed:
- Create a
prismjs.cssfile with the following content:
prismjs-css
/* Tailwind CSS */
@import "./globals.css";
/* Prism - One Light (Light Mode) */
:root {
--prism-comment: #a0a1a7;
--prism-punctuation: #383a42;
--prism-tag: #e45649;
--prism-selector: #e45649;
--prism-property: #986801;
--prism-boolean: #986801;
--prism-number: #986801;
--prism-constant: #986801;
--prism-symbol: #986801;
--prism-attr-name: #986801;
--prism-deleted: #986801;
--prism-string: #50a14f;
--prism-attr-value: #50a14f;
--prism-builtin: #50a14f;
--prism-inserted: #50a14f;
--prism-operator: #0184bc;
--prism-url: #0184bc;
--prism-keyword: #a626a4;
--prism-atrule: #a626a4;
--prism-regex: #a626a4;
--prism-variable: #a626a4;
--prism-function: #4078f2;
--prism-class-name: #c18401;
}
/* Prism - One Dark Pro (Dark Mode) */
.dark {
--prism-comment: #5c6370;
--prism-punctuation: #abb2bf;
--prism-tag: #e06c75;
--prism-selector: #e06c75;
--prism-property: #d19a66;
--prism-boolean: #d19a66;
--prism-number: #d19a66;
--prism-constant: #d19a66;
--prism-symbol: #d19a66;
--prism-attr-name: #d19a66;
--prism-deleted: #d19a66;
--prism-string: #98c379;
--prism-attr-value: #98c379;
--prism-builtin: #98c379;
--prism-inserted: #98c379;
--prism-operator: #56b6c2;
--prism-url: #56b6c2;
--prism-keyword: #c678dd;
--prism-atrule: #c678dd;
--prism-regex: #c678dd;
--prism-variable: #c678dd;
--prism-function: #61afef;
--prism-class-name: #e5c07b;
}
/* Prism Token Colors */
.token.comment,
.token.prolog,
.token.doctype,
.token.cdata {
color: var(--prism-comment);
font-style: italic;
}
.token.punctuation {
color: var(--prism-punctuation);
}
.token.tag,
.token.selector {
color: var(--prism-tag);
}
.token.property,
.token.boolean,
.token.number,
.token.constant,
.token.symbol,
.token.attr-name,
.token.deleted {
color: var(--prism-property);
}
.token.string,
.token.char,
.token.attr-value,
.token.builtin,
.token.inserted {
color: var(--prism-string);
}
.token.operator,
.token.entity,
.token.url {
color: var(--prism-operator);
}
.token.atrule,
.token.keyword {
color: var(--prism-keyword);
}
.token.function {
color: var(--prism-function);
}
.token.class-name {
color: var(--prism-class-name);
}
.token.regex,
.token.important,
.token.variable {
color: var(--prism-regex);
}
.token.important,
.token.bold {
font-weight: bold;
}
.token.italic {
font-style: italic;
}
.token.entity {
cursor: help;
}
/* Font for <code> element */
code {
@apply font-mono;
}
/* Spacing to match Shiki layout */
pre.prism-pre {
@apply py-3;
}
pre.prism-pre code {
@apply block px-4 leading-[1.6] whitespace-pre;
}
/* Line Numbers */
pre.prism-line-numbers code {
counter-reset: prism-line-number;
}
pre.prism-line-numbers .prism__line::before {
counter-increment: prism-line-number 1;
content: counter(prism-line-number);
width: 0.5rem;
margin-right: 1.3rem;
margin-left: 0.2rem;
display: inline-block;
@apply text-right font-mono text-xs text-neutral-500;
}- Import the CSS file in your global layout:
import "@/styles/prismjs.css";Usage
You can use the highlight function to get syntax highlighted code. For example:
Prismjs Highlighter Usage
import { highlight } from "@/utils/prismjs/highlight";
const code = `console.log('hello')`;
const highlighted = highlight({ code, language: "ts" });Supported Languages
The utility pre-loads: ts, jsx, tsx, bash, json, css, markdown. You can add more by importing additional Prismjs language components:
import "prismjs/components/prism-python";
import "prismjs/components/prism-rust";