본문 바로가기

main/Next.js

[Next.js] SEO를 위한 SSR 시도 - 페이지별og태그 적용기

그냥 전체 페이지에 og태그는 적용이 잘 되는데

나는 각각의 포스트 페이지에 그 페이지에 맞는 og태그를 적용시켜주고 싶었다.

 

해당 페이지 코드에서 useEffect(), next-seo 라이브러리, getServerSideProps, getStaticProps/Paths 를 모두 사용해보았다.

빌드 후 페이지에서 확인을 해보면 마치 적용이 된 것 처럼 보였으나

사실은 html 파일 자체에 적용되어 전송된게 아니라 적용되지 않은 페이지에서 js로 인해 바뀐 상태가 보여진 것이다.

 

그래서 카카오톡 공유를 하면 계속 이렇게 og가 없는 .. 상태로 나왔다. 페이지에서는 og가 확인이 됨에도 불구하고.

 

Next.js에서 제공되는 기본 코드를 봐도 그냥 페이지에 입력해서 잘 적용 되는거 같은데 나는 왜 이러는건지 모르겠다...

내가 뭘 잘못하고있는건지 이유를 알고싶다.

어쨌든 나는, 이 방법이 맞는지는 아직 확신이 없지만

(ㅠㅠ왜냐면 메타태그 _document에서 쓰는게 아니었던가. ..? _app.jsx에 이런 로직 같은 코드들이 들어있어도 되는건가 하는 생각)

일단 적용이 되니까 이렇게 진행은 했다..

 

1. [id].tsx 페이지에서 전체 포스트를 조회하고 현재 페이지의 id에 해당하는 내용을 article에 담아 pageProps로 보내준다.

// [id].tsx

import React from "react";
import Detail from "components/article/Detail";
import { GetStaticPaths, GetStaticProps, NextPage } from "next";
import fetch from "isomorphic-unfetch";

interface IProps {
  article: {
    ...
  };
}

const Article: NextPage<IProps> = () => {
  return <Detail />;
};

export const getStaticProps: GetStaticProps = async ({ params }: any) => {
  const res = await fetch(`...?id=${params.id}}`);
  const article = await res.json();
  return {
    props: { article }
  };
};

export const getStaticPaths: GetStaticPaths = async () => {
  const res = await fetch(`${.../articles`);
  const articles = await res.json();
  const paths = articles.map((article: any) => ({
    params: {
      id: article.a_id.toString()
    }
  }));

  return {
    paths,
    fallback: false
  };
};

export default Article;

2. 이후에 _app.jsx에서 meta태그 삽입 시 article이 있는지 없는지에 따라 로직을 수행했다.

import React, { useEffect, useState, createElement } from "react";
import Head from "next/head";

const App = ({ Component, pageProps }) => {
  const article = pageProps?.article;

  return (
    <>
      <Head>
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>{article && `${article.a_title} - `}blabla</title>
        <meta property="og:title" content={article ? `${article.a_title} - blabla` : "blabla"} />
        <meta name="title" content={article ? `${article.a_title} - blabla` : "blabla"} />
        <meta
          name="description"
          content={
            article
              ? ...
              : ...
          }
        />
        <meta property="og:type" content="website" />
        <meta
          property="og:description"
          content={
            article
              ? ...
              : ...
          }
        />
        <meta property="og:image" content={article ? `...` : "..."} />
      </Head>
    </>
  );
};

export default App;

 

이렇게 빌드해서 url을 보내 보면 이제 원하는 대로 나오긴 함.

혹시 안 나온다면 아래 링크에서 캐시를 삭제해주면 나올 것이닷

https://developers.kakao.com/tool/clear/og

 

하지만 이대로 진행하기엔 아직 해결되지 않은 부분이 많다.

 

매번 이렇게 빌드를 할때마다 정적파일을 만들어 올려야 한다면 ,.. 글 하나하나 작성시마다 빌드후 재배포가 되어야 하나?

그렇다면 이미 빌드된 애들은 쓸데없이 다시 빌드가 되어야 하는가..?

매번 이렇게 빌드 후 파일이 적용되면 글 업로드에 시간이 오래 걸리지는 않나?

😵‍💫

 

그리고 코드에 타입 적용도 제대로 하고 싶었는데 안 돼서 우선 any행 ... 휴 정말 ... 그래도 차근차근 해나가야지. 갈길이 멀다!