Network 탭에서 해당 url 요청 preview 탭에서 확인
개발자 도구 Settings - Preferences - Debugger에서 'Disable JavaScript' 체크 후 확인
SSR이 적용되었는지 확인을 해보니 제목, 사이드바 내용들은 적용되어 있었지만 가장 중요한 본문이 적용이 되지 않고 있었다.
코드는 다음과 같이 구현되어 있었다.
const editor = useEditor({
extensions: handleTiptapExtensions('memo', memoId),
editorProps: handleTiptapEditorProps('memo', memoId),
editable: false,
content: content,
});
useEffect(() => {
editor?.commands.setContent(content);
}, [content]);
return (
<div className="px-4 flex-grow break-all">
<EditorContent editor={editor} />
</div>
)
content 데이터(tiptap의 JSON 데이터)는 서버 사이드에서 불러오고 있었지만 바로 사용되지 않고 클라이언트 사이드에서 useEditor라는 훅과 그로부터 나온 데이터를 EditorContent 컴포넌트에 props로 전달해주는 데 사용된다.
https://tiptap.dev/guide/output 서 해결책을 찾을 수 있었다.
tiptap의 렌더링 방식으로 두 가지가 있다.
Read-only instance of tiptap
내가 처음 구현한 방식이다. useEditor를 사용하고 editable option을 false로 준다.
JSON으로부터 HTML 생성하기
서버 사이드에서 렌더링할 수 있도록 설정이 가능하다.
// Option 1: Browser + server-side
import { generateHTML } from '@tiptap/html'
import React, { useMemo } from 'react'
export default () => {
const output = useMemo(() => {
return generateHTML(content, handleTiptapExtensions('memo', memoId));
}, [content]);
return (
<div className="px-4 flex-grow break-all"
dangerouslySetInnerHTML={{ __html: output }}
></div>
)
}
다음과 같이 변경해 SSR을 구현할 수 있다.
중요한 거는 generateHTML은 '@tiptap/html' 에서 가져와야 한다. '@tiptap/react'에서 가져오면 server side에서 렌더링 되지 않는다!
+ danerouslySetInnerHTML
브라우저 DOM에서 innerHTML을 사용하기 위한 React의 대체 방법
일반적으로 코드에서 HTML을 설정하는 것은 XSS 공격에 노출될 수 있기 때문에 위험..!
이를 상기시키기 위해 다음과 같은 옵션이 존재
XSS 공격은 input태그 관련해서 발생하는 거라서 단순 게시글 보여주는 지금 같은 case는 괜찮지 않을까라는 생각..? -> 이건 조사 더 필요