Use highlighted codestandard
코드 글을 줄마다 색 입힌 React 노드로 바꾸는 훅(hook)과 도우미입니다. shadcn base-nova 의 원본을 그대로 담은 아이템이며 shiki 의 JavaScript 정규식 엔진을 씁니다. 언어는 처음 쓰일 때 하나씩 불러옵니다. 업스트림 메타데이터에 문서 링크가 없습니다. `code-block` 이 이 아이템을 씁니다.
설치
pnpm dlx shadcn@4.23.0 add @uikit/use-highlighted-code코드 글을 줄마다 색 입힌 React 노드로 바꾸는 훅(hook)과 도우미입니다. shadcn base-nova 의 원본을 그대로 담은 아이템이며 shiki 의 JavaScript 정규식 엔진을 씁니다. 언어는 처음 쓰일 때 하나씩 불러옵니다. 업스트림 메타데이터에 문서 링크가 없습니다. code-block 이 이 아이템을 씁니다.
설치
pnpm dlx shadcn@4.23.0 add @uikit/use-highlighted-code사용
"use client";
import { CodeBlock, CodeBlockContent, CodeBlockLine } from "@/components/ui/code-block";import { useHighlightedCode } from "@/hooks/use-highlighted-code";
export function Snippet({ code }: { code: string }) { const lines = useHighlightedCode(code, "typescript"); return ( <CodeBlock> <CodeBlockContent lineNumbers> {lines.map((line, index) => ( <CodeBlockLine key={index}>{line}</CodeBlockLine> ))} </CodeBlockContent> </CodeBlock> );}속성
설치하면 파일 두 개가 놓입니다.
| 내보내기 | 파일 | 뜻 |
|---|---|---|
useHighlightedCode(value, language) | @/hooks/use-highlighted-code | 줄마다 React.ReactNode 하나인 배열을 돌려줍니다. 언어를 불러오는 동안과 목록에 없는 언어는 줄 문자열 그대로입니다 |
loadHighlighter(language) | @/lib/highlighter | 언어를 불러와 { highlight(code, state?) } 를 돌려줍니다. 목록에 없으면 null |
highlightCode(code, language) | @/lib/highlighter | 한 번에 줄 노드 배열을 돌려줍니다. 목록에 없으면 null |
tokenColorReplacements | @/lib/highlighter | 테마별 글자색 교체표 |
highlight 는 { lines, state } 를 돌려주며 state 를 다음 호출에 넘기면 앞 줄의 문법 상태를 이어 갑니다. 지원 언어는 bash, css, diff, html, javascript, json, jsonc, jsx, markdown, python, sql, tsx, typescript, yaml, ansi, text 이며 별칭 js, ts, sh, shell, shellscript, zsh, md, py, yml, plain, plaintext, txt 를 풉니다. text 는 색 없이 줄만 나눕니다. 목록에 없는 언어는 던지지 않고 null 입니다. 언어를 늘리려면 @/lib/highlighter 의 languages 에 줄을 더합니다. 밝은·어두운 테마는 github-light·github-dark 입니다.
tokenColorReplacements 는 테마 이름별 «원래 색 → 바꾼 색» 표로, shiki 의 colorReplacements 로 넘깁니다. 두 테마가 낼 수 있는 모든 글자색이 background·muted(강조·추가 줄)·destructive/10(삭제 줄) 바탕에서 4.5:1 이상이 되게 모자란 색만 바꿉니다.
highlightCode 와 loadHighlighter 는 "use client" 가 없어 서버 컴포넌트(React Server Component)에서 그대로 await 할 수 있습니다. 훅 useHighlightedCode 는 클라이언트 전용입니다.
import { highlightCode } from "@/lib/highlighter";
export async function ServerSnippet({ code }: { code: string }) { const lines = await highlightCode(code, "tsx"); return <pre>{lines ?? code}</pre>;}기본으로 지키는 것
- 끝의 개행 하나는 빈 줄을 만들지 않습니다.
- 글이 이어 붙어 자라면(스트리밍) 이미 끝난 줄은 다시 색 입히지 않고 앞 줄의 문법 상태에서 이어 갑니다. 마지막 줄만 매번 다시 입힙니다.
- 언어를 바꾸면 새 언어가 불러와질 때까지 줄 문자열로 돌아갑니다.
- 언어 이름은 대소문자를 가리지 않습니다. 목록에 없는 언어는
null이고 훅은 문자열을 유지합니다.constructor·__proto__같은 상속된 이름도 목록에 없는 언어로 다룹니다. - 불러오는 중 언마운트해도 상태를 바꾸지 않습니다. 불러오기 오류는 삼키고 문자열을 유지합니다.
- 색은
--shiki-light·--shiki-dark변수와dark:클래스로 입힙니다. - 밝은·어두운 테마의 모든 글자색은 코드 블록 바탕에서 4.5:1 이상입니다. 원래
github-light의#e36209는 흰 바탕에서 3.48:1 입니다.
접근성
글자만 색이 다를 뿐 글 구조는 같고 색만으로 뜻을 전하지 않습니다.
의존
npm: shiki. 다른 아이템은 쓰지 않습니다.