yarn add react-quill
import ReactQuill from 'react-quill';
import 'react-quill/dist/quill.snow.css';
return(
<div>
내용 : <ReactQuill onChange={onChangeContents} />
</div>
)
-> 다이나믹 임포트 해야함
// import ReactQuill from 'react-quill';
import 'react-quill/dist/quill.snow.css'; // ES6
import dynamic from 'next/dynamic';
// 다이나믹 임포트
const ReactQuill = dynamic(()=> import("react-quill"), {ssr : false})
// 서버사이트렌더링(ssr) false -> 브라우저에서만 그리겠다
register로 등록하지 않고 강제로 값을 넣어주는 기능
const {register, handleSubmit, setValue} = useForm({
mode : "onChange"
})
const onChangeContents = (value:string) =>{
console.log(value)
// register로 등록하지 않고 강제로 값을 넣어주는 기능
setValue("contents", value)
}
setValue를 이용한다.
onChange 됐다고 react-hook-form에 알려주는 기능
const {register, handleSubmit, setValue, trigger } = useForm({
mode : "onChange"
})
const onChangeContents = (value:string) =>{
console.log(value)
// register로 등록하지 않고 강제로 값을 넣어주는 기능
setValue("contents", value === "<p><br></p>" ? "" : value)
// 내용부분 다 지워도 남는 태그들 때문에 빈칸으로 처리 안되므로 저 태그들만 있을때 빈칸으로 만들어줌
trigger("contents")
// onChange 됐다고 react-hook-form에 알려주는 기능
}
react-quill에 내용을 다 지워도 "
내용이 있을때만 등록하기 버튼이 활성화 되게 하기위해서 setValue에 조건을 넣어줌
출력시
이렇게 태그가 같이 나오는 것을 막으려면
<div dangerouslySetInnerHTML={{
__html: data?.fetchBoard.contents,
}}></div>
그런데 SetInnerHTML은 위험하다!
react-quill은 직접 꺽쇠를 입력하면 < 등으로 막아놨다(
하지만 플레이그라운드에서 직접 보내면
사이트에 들어왔을때 이렇게 토큰 탈취가 가능하다(Cross-Site-Script, XSS).
dompurify 라이브러리 적용
yarn add dompurify
import Dompurify from 'dompurify'
<div dangerouslySetInnerHTML={{
__html: Dompurify.sanitize(data?.fetchBoard.contents),
}}></div>
하면 또 프리렌더링 에러가 뜬다.
해결하려면
{typeof window !== "undefined" && (<div dangerouslySetInnerHTML={{
__html: Dompurify.sanitize(data?.fetchBoard.contents),
}}></div>)}