트러블슈팅
에러 메시지별로 원인 → 해결책 순서로 정리했습니다. 개념 설명은 각 링크 문서 참고.
Hydration mismatch
증상: Hydration failed because the server rendered HTML didn't match the client + 에디터가 깜빡이며 다시 렌더링됨.
원인: 서버 셸 HTML과 클라이언트 첫 렌더 HTML이 다릅니다. 흔한 원인은
content를 인라인 객체로 넘겨서 렌더마다 새로 계산되는 경우입니다.
해결: 콘텐츠 참조를 고정하세요.
// Before: 렌더마다 새 객체 → 셸과 불일치 가능
<Editor content={{ type: 'doc', content: [...] }} />
// After: 안정 참조
const content = useMemo(() => ({ type: 'doc', content: [...] }), []);
<Editor content={content} />서버·클라이언트 양쪽에서 동일한 extensions를 넘기는지도 확인하세요.
자세한 동작은 SSR 참고.
window is not defined / document is not defined
증상: Next.js 빌드·서버 렌더 중 ReferenceError.
원인: 에디터 컴포넌트를 Server Component에서 직접 렌더링했습니다.
Editor/Viewer는 'use client'라서 클라이언트 경계 안에서만 동작합니다.
해결: 사용하는 페이지(또는 래퍼)에 'use client'를 선언하세요.
'use client';
import { Editor } from '@inkio/editor';
export function Page() {
return <Editor content="<p>Hello</p>" />;
}스타일이 적용되지 않음
증상: 에디터는 뜨는데 테마 없이 밋밋하게 보임.
원인 1: CSS import 누락. 패키지별 진입점에서 한 번 import해야 합니다.
import '@inkio/editor/style.css'; // 또는 simple/image-editor원인 2: minimal.css를 썼는데 색상·폰트가 없음. minimal은 레이아웃과
구조만 포함하므로, 디자인 토큰을 직접 정의하지 않았다면 style.css를 쓰세요.
자세한 계약은 컴포넌트 → CSS 참고.
번들이 갑자기 커짐
증상: 클라이언트 JS가 수백 KB 증가.
원인 1: 마크다운 subpath를 클라이언트 컴포넌트 모듈 레벨에서 import.
remark/unified가 클라이언트 번들에 딸려옵니다 (루트에서는 re-export하지
않으므로 루트 import는 실패합니다).
// Before: 클라이언트 번들에 remark 포함
import { parseMarkdown } from '@inkio/editor/markdown';
const html = parseMarkdown(src); // 모듈 레벨 실행
// After: 서버 코드·이벤트 핸들러 안에서만 사용
async function onImport(src: string) {
const { parseMarkdown } = await import('@inkio/editor/markdown');
return parseMarkdown(src);
}원인 2: classic 용도에 notion-like 프리셋 사용. @inkio/simple이
가장 가볍습니다. 패키지별 상한은 node scripts/check-budgets.mjs로 확인하세요.
Tiptap 관련 타입·런타임 충돌
증상: Duplicate Tiptap instance, 확장 인식 실패, 원인 불명 오동작.
원인: @tiptap/* 패키지를 직접 설치해서 Inkio 내장 런타임과 별개
복사본이 생겼습니다.
해결: 직접 설치한 @tiptap/*를 지우세요. 꼭 직접 조합해야 하면
버전을 Inkio 의존과 맞추세요. 확장 → 커스텀 확장 참고.
협업 상태가 connecting에서 안 넘어감
증상: useInkioCollaborativeEditor의 status가 계속 connecting.
원인: 대부분 URL 문제입니다. Hocuspocus는 WebSocket이라 http://가 아니라
ws://(배포 환경은 wss://)로 접속해야 하고, 서버가 그 포트에서 떠 있어야 합니다.
해결: URL 스킴과 포트를 확인하세요.
useInkioCollaborativeEditor({
docId,
url: 'ws://localhost:3123', // ← http:// 아님
// ...
});unauthorized로 바뀐다면 서버 verify가 토큰을 거부한 것입니다.
자세한 내용은 실시간 협업 참고.