SSR로부터 HTML 텍스트를 받아오면
dangerouslySetInnerHTML를 사용하여 웹 페이지 안에 삽입 할 수 있다.
import React, { useEffect } from 'react'
import Head from 'next/head'
const externalPage = ({data}) => {
const htmlString = data.html_text
function Template({ htmlString }) {
return <div dangerouslySetInnerHTML={{ __html: htmlString }}></div>
}
return (
<section>
<Template htmlString={htmlString} />
</section>
)
}
next.js의 <HEAD>
태그안에 <link>
태그를 넣어 css파일을 연결하면 해당 페이지에 css를 적용시킬 수 있다.
import React, { useEffect } from 'react'
import Head from 'next/head'
const externalPage = ({data}) => {
const htmlString = data.html_text
const pageStyle = `${data.css_file}`
function Template({ htmlString }) {
return <div dangerouslySetInnerHTML={{ __html: htmlString }}></div>
}
return (
<>
<Head>
<link rel="stylesheet" href={pageStyle} />
</Head>
<section>
<Template htmlString={htmlString} />
</section>
)
</>
}
외부 파일의 JavaSrcipt를 실행시키려면 Window.postMessage()를 활용하는 방법이 있다.
window.postMessage() 메소드는 Window 오브젝트 사이에서 안전하게 cross-origin 통신을 할 수 있다고 한다.
// 외부 HTML
<body>
<div class="input">
<button class="inquiry_btn">
문의하기
</button>
</div>
<script type="text/javascript">
var btn = document.querySelectorAll(".inquiry_btn")[0];
function onClick(e) {
e.preventDefault();
const name = document.getElementById('name')
const contents = document.getElementById('contents')
if(name['value'] === '') {
alert('이름을 입력해주세요');
return;
}
if(contents['value'] === '') {
alert('요청사항을 입력해주세요');
return;
}
window.postMessage({
functionName: 'postInquiry',
data: {
request_name: name['value'],
request_content: contents['value'],
}}, '*');
}
btn.addEventListener('click', onClick);
</script>
</body>
// next.js Page
import React, { useEffect } from 'react'
import Head from 'next/head'
const externalPage = ({data}) => {
const htmlString = data.html_text
const pageStyle = `${data.css_file}`
function Template({ htmlString }) {
return <div dangerouslySetInnerHTML={{ __html: htmlString }}></div>
}
const postInquiry = async (e) => {
e.preventDefault()
try {
const result = await API.post(
`/(api주소)`,
e.data.data
)
if (result.status === 200) {
alert('문의 작성이 완료되었습니다.')
}
return
} catch (err) {
console.log(err)
}
}
const receiveMessage = (e) => {
e.preventDefault()
if (e.data.functionName == 'postInquiry') {
postInquiry(e)
}
}
// useEffect로 receiveMessage함수가 실행되고 next.js에 있는 함수를 실행시키는데
e.data.functionName == 'postInquiry'라는 조건을 걸어 원하는 타이밍에 함수를 실행시킬수 있다.
useEffect(() => {
window.addEventListener('message', receiveMessage)
return () => {
window.removeEventListener('message', receiveMessage)
}
}, [])
return (
<>
<Head>
<link rel="stylesheet" href={pageStyle} />
</Head>
<section>
<Template htmlString={htmlString} />
</section>
)
</>
}
HTML의 버튼을 누르면 script의 onClick 함수가 실행되고 그 결과를 window.postMessage()를 통해 next.js에 보내면 받은 event를 통해 next.js에서 계속해서 활용 할 수 있다.