Quartz 4.0에 Disqus를 추가하기 위해 quartz/components 폴더에 Disqus.tsx를 추가하고, 같은 폴더의 renderPage.tsx를 일부 수정한다.

Disqus.tsx 파일

import { FunctionComponent } from "preact"

interface DisqusProps {
  slug: string
}

const Disqus: FunctionComponent<DisqusProps> = ({ slug }) => {
  return (
    <div id="disqus_thread" data-slug={slug} style="color-scheme: normal"></div>
  )
}

export const disqusScript = `
  var disqus_config = function () {
    this.page.url = window.location.href;
    this.page.identifier = document.getElementById('disqus_thread').dataset.slug;
  };

  setTimeout(function() {
    var d = document, s = d.createElement('script');
    s.src = 'https://idencosmos.disqus.com/embed.js';
    s.setAttribute('data-timestamp', +new Date());
    (d.head || d.body).appendChild(s);
  }, 500);  // 0.5초 후에 로드
`


export default Disqus

0.5초(최초 3초) 후에 Disqus가 로드되도록 설정했다. 그렇지 않으면 Disqus가 새로고침 후에만 로드가 되었다. 아마 페이지 로딩 초기에 로드되어서 그런거 같다.

renderPage.tsx 수정

Disqus.tsx에서 Disqus와 disqusScript를 import 한다.

import Disqus, { disqusScript } from "./Disqus" // custom component

가장 아랫부분의 전체 페이지를 로딩하는 부분에서 해당 내용을 추가한다.

  const lang = componentData.fileData.frontmatter?.lang ?? cfg.locale?.split("-")[0] ?? "en"
  const doc = (
    <html lang={lang}>
      <Head {...componentData} />
      <body data-slug={slug}>
        <div id="quartz-root" class="page">
          <Body {...componentData}>
            {LeftComponent}
            <div class="center">
              <div class="page-header">
                <Header {...componentData}>
                  {header.map((HeaderComponent) => (
                    <HeaderComponent {...componentData} />
                  ))}
                </Header>
                <div class="popover-hint">
                  {beforeBody.map((BodyComponent) => (
                    <BodyComponent {...componentData} />
                  ))}
                </div>
              </div>
              <Content {...componentData} />
              {componentData.fileData.frontmatter?.disqus && <Disqus slug={slug} />}
            </div>
            {RightComponent}
          </Body>
          <Footer {...componentData} />
        </div>
      </body>
      {pageResources.js
        .filter((resource) => resource.loadTime === "afterDOMReady")
        .map((res) => JSResourceToScriptElement(res))}
      {componentData.fileData.frontmatter?.disqus && (
        <script data-cfasync="false" type="text/javascript" dangerouslySetInnerHTML={{ __html: disqusScript }} />
      )}
    </html>
  )

<script data-cfasync="false" type="text/javascript" dangerouslySetInnerHTML={{ __html: disqusScript }} /> 부분을 보면, data-cfasync="false"부분이 있다. 이 부분이 있어야, 클라우드 플레어의 Rocket Loader를 활성화 한 상태에서 Disqus가 제대로 작동한다.

Disqus 적용

문서 프론트메타에 disqus: true를 추가해서 적용한다.

CloudFlare Pages 로딩 오류

처음 게시글을 로딩하면 Disqus가 로딩이 안 되는 문제가 발생할 수 있다. 이 문제는 CloudFlare에서 [ Speed | Optimization | Content Optimization ] 항목의 Rocket Loader™을 해제해서 해결했다.