Gu Doyoon

Highlight.js로 코드 하이라이팅 + 넘버링 구현

1/23/2026 작성

학습 플랫폼에서 사용자의 몰입도를 높이는 가장 중요한 요소 중 하나는 콘텐츠의 '가독성'입니다. 특히 코딩을 배우는 입문자에게 실제 개발 환경과 유사한 경험을 제공하는 것은 학습 효율과 직접적으로 연결된다고 생각했습니다.

이번 글에서는 Coko 프로젝트에서 밋밋한 텍스트에 불과했던 코드 블록을, 어떻게 재사용 가능한 React 커스텀 훅으로 발전시키고, IDE와 같은 생생한 학습 경험을 제공하게 되었는지 그 과정을 공유하고자 합니다.

하이라이팅 구현

기술 스택 선정하기

이 문제를 해결하기 위해 직접 파싱 로직을 구현하는 것은 지나치게 많은 공수가 든다고 판단, 검증된 라이브러리를 활용하기로 했습니다. 여러 후보군 중 저희 팀이 선택한 라이브러리는 Highlight.js였습니다.

구현 내용

import hljs from 'highlight.js'; import { DependencyList, useState, useLayoutEffect } from 'react'; /** * 주어진 코드 문자열을 하이라이트 처리된 HTML로 변환하는 React 커스텀 훅입니다. * * `highlight.js` 라이브러리를 사용하여 특정 언어의 코드 구문을 강조하고, * 이를 하이라이트 처리된 HTML 문자열로 반환합니다. * 의존성 배열(`deps`)을 통해 재렌더링 조건을 제어할 수 있습니다. * 코드 "문자열" 을 반환하기 때문에 html-react-parser과 xss에 취약한 점을 보완하기 위해 dompurify를 같이 사용하는것을 권장드립니다. * * @param {string} code - 하이라이트 처리할 코드 문자열. * @param {DependencyList} [deps] - 훅 실행을 제어할 의존성 배열. 기본값은 `undefined`이며, 이 경우 `code`와 `language`를 기본 의존성으로 사용합니다. * @param {string} [language='javascript'] - 코드 하이라이트에 사용할 언어. 기본값은 'javascript'입니다. * @returns {string} 하이라이트 처리된 HTML 문자열. * * @example * const code = ` * const greet = (name) => { * console.log(\`Hello, \${name}!\`); * }; * greet('World'); * `; * * const highlightedCode = useCodeHighlight(code, [code], 'javascript'); * * return ( * <pre> * <code> * {parse(dompurify.sanitize(addLineNumberCode), options)} * </code> * </pre> * ); */ const useCodeHighlight = ( code: string, deps?: DependencyList, language: string = 'javascript' ) => { const [highlightCode, setHighlightCode] = useState<string>(''); useLayoutEffect(() => { try { hljs.configure({ ignoreUnescapedHTML: true }); const highlightedCode = hljs.highlight(code, { language }).value; setHighlightCode(highlightedCode); } catch (error) { setHighlightCode(code); } }, deps ?? [code, language]); return highlightCode; }; export default useCodeHighlight;

설계 포인트

사용자를 위한 Line Number 제안

기본적인 하이라이팅 기능 구현 후, 어떻게 하면 사용자가 코드를 더 쉽게 읽을 수 있을까? 라는 고민을 하게 되었습니다. 저는 팀에 코드 옆에 라인 넘버를 추가하는 아이디어를 제안했고, 팀원들의 긍정적인 반응을 얻어 즉시 개발에 착수했습니다.

데이터베이스에 저장된 코드 문자열이 \n (줄바꿈) 문자를 포함하고 있다는 점을 활용하여 간단한 유틸 함수를 작성했습니다.

/** * 코드 문자열의 각 줄에 줄 번호를 추가합니다. * @param {string} code - 줄 번호를 추가할 코드 문자열. * @returns {string} 각 줄에 줄 번호가 추가된 문자열. */ const addLineNumbersToCode = (code: string) => { return code .split('\n') .map((line, i) => `<span>${i + 1} |</span> ${line}`) .join('\n'); }; export default addLineNumbersToCode;

결과물!

두 가지 기능이 결합된 최종 결과물은 학습자의 가독성과 편의성을 크게 향상시켰습니다.

Highlight.js로 코드 하이라이팅 + 넘버링 구현 | 구도윤 기술 블로그