SSG, SSR 을 통해 구현한 링크 공유 미리보기 이미지 (og image)

배경

  • next.js 에서 dynamic routes 를 통해 여러 테스트에 대한 페이지를 렌더링하고자 한다
  • 이 페이지를 링크로 공유했을 때 각 테스트에 대한 미리보기 이미지를 og (open graph) 로 구현하고자 한다
  • 코드 예
const router = useRouter()
const testId = (Array.isArray(router.query.testId) ? router.query.testId[0] : router.query.testId) || ""

// ...
const ogImgUrl = useMemo(()=>{
    return testId === "food" 
      ? "이미지주소1"
      : "이미지주소2" 
  },[testId])

// ...

<NextSeo
  title={pageTitle}
  description={ogDescription}
  openGraph={{
    title: WEBSITE_TITLE,
      images: [
        {
          url: ogImgUrl,
          width: 1200,
          height: 630,
        },
      ],
  }}
  />

문제점

  • www.도메인.com/tests/[testId] 에서 testId 을 읽고, 어떤 테스트인지 파악하는 코드가 "next/router" 의 useRouter 을 이용해서 구현했는데, 이는 브라우저에서의 동작이 필요로 한다
    • 즉 서버에서 렌더링되는 시점에선 어떤 테스트 (testId) 인지 알 수 없기에 ogImgUrl 에 제대로 된 이미지 주소가 할당되지 않는다
    • 따라서 og 태그가 제대로 렌더링되지 않는다
    • 즉 링크를 공유했을 때 이미지가 뜨지 않는다.

해결책

  • SSG 혹은 SSR을 이용한다
    • useRouter 대신 getStaticProps 혹은 getServerSideProps 에서 testId 값을 읽어서 관련 로직을 수행한다
    • www.도메인.com/tests/[testId] 같이 path 값만을 이용할때는 getStaticProps 을 이용하면 되지만,
      www.도메인.com/tests/[testId]q?=test 같이 search query 를 읽어오기 위해선 getServerSideProps 을 이용해야 한다
  • 코드 예
export const getStaticPaths: GetStaticPaths = () => {
  return {
    paths: [{params: {testId: "food"}}, {params: {testId: "knowledge"}}],
    fallback: true,
  };
}

export const getStaticProps: GetStaticProps = (context) => {
  const testId = context?.params?.testId || ""

  return {
    props: {
      testId: testId === "food" ? "food" : "knowledge"
    },
  }
}

또는

export const getServerSideProps: GetServerSideProps = async (context) => {
  const testId = context?.params?.testId || ""
  const scoreParam = context?.query?.s || ""
  const encryptedScore = typeof scoreParam === "string" ? scoreParam : ""
  const decryptedScore = encryptedScore ? parseInt(decrypt(encryptedScore), 10) : -1

  return {
    props: {
      testId: testId === "food" ? "food" : "knowledge",
      defaultScore: decryptedScore
    },
  }
}

좋은 웹페이지 즐겨찾기