Dev

meta 태그

minsun309 2024. 8. 23. 00:07

meta 태그

<meta> 태그는 HTML 문서의 <head>와 </head> 사이에 입력하는 특수 태그로서 해당 문서에 대한 정보인 메타데이터(metadata)를 정의할 때 사용합니다.

  • viewport - 반응 형 웹 구현
<meta name="viewport" content="width=device-width, initial-scale=1">
  • Keywords - 검색엔진에 의해 검색되는 단어 지정
<meta name="keywords" content="HTML, CSS, JavaScript">
  • Description - 검색 결과에 표시되는 문자 지정
<meta name="description" content="탐구한 것들을 기록하는 장소입니다." />
  • author - 웹 페이지의 소유자(또는 회사) 작성
<meta name="author " content="minsun">

 

 

OpenGraph

오픈그래프는 웹페이지가 소셜 미디어 또는 오픈그래프를 활용한 사이트로 공유될때 사용되어지는 정보이다.

 

기본적으로 설정해야하는 og 메타태그

<meta property="og:type" content="website">
<meta property="og:url" content="https://example.com/page.html">
<meta property="og:title" content="Content Title">
<meta property="og:image" content="https://example.com/image.jpg">
<meta property="og:description" content="Description Here">
<meta property="og:site_name" content="Site Name">
<meta property="og:locale" content="en_US">
<!-- 다음의 태그는 필수는 아니지만, 포함하는 것을 추천함 -->
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">

 

Naver 블로그, 카카오톡 미리보기 설정

<meta property="og:title" content="콘텐츠 제목" /> 
<meta property="og:url" content="웹페이지 URL" />
<meta property="og:type" content="웹페이지 타입(blog, website 등)" />
<meta property="og:image" content="표시되는 이미지" /> 
<meta property="og:title" content="웹사이트 이름" /> 
<meta property="og:description" content="웹페이지 설명" />

 

트위터 미리보기 설정

<meta name="twitter:card" content="트위터 카드 타입(요약정보, 사진, 비디오)" /> 
<meta name="twitter:title" content="콘텐츠 제목" /> 
<meta name="twitter:description" content="웹페이지 설명" /> 
<meta name="twitter:image" content="표시되는 이미지 " />

 

모바일 앱 미리보기 설정

<--iOS-->
<meta property="al:ios:url" content=" ios 앱 URL" />
<meta property="al:ios:app_store_id" content="ios 앱스토어 ID" /> 
<meta property="al:ios:app_name" content="ios 앱 이름" /> 
 
<--Android-->
<meta property="al:android:url" content="안드로이드 앱 URL" />
<meta property="al:android:app_name" content="안드로이드 앱 이름" />
<meta property="al:android:package" content="안드로이드 패키지 이름" /> 
<meta property="al:web:url" content="안드로이드 앱 URL" />

 

 

Next.js에서 meta 태그 적용하기

  • 정적 메타 태그

개인적으로 Layout에서 화면 구성을 하고 싶어서 seo를 컴포넌트 화 시킨 후 Layout파일에 배치시킨 후 최상단인 _app.tsx에 Component 를 Layout로 감쌌다.

 

// components/seo.tsx
import Head from "next/head";

export default function Seo() {
  return (
    <Head>
      <title>MinSun's Blog</title>
		  <meta name="viewport" content="initial-scale=1.0, width=device-width" />
      <meta property="og:title" content={"MinSun's Blog"} />
      <meta property="og:site_name" content="MinSun's Blog" />
      <meta
        property="og:description"
        content={"탐구한 것들을 기록하는 장소입니다."}
      />
      <meta property="og:type" content="website" />
      <meta property="og:url" content={"https://min-sun.vercel.app/"} />
      <meta
        property="og:image"
        content={"https://images.unsplash.com/image"}
      />
      <meta property="og:image:width" content="1200" />
      <meta property="og:image:height" content="630" />
      <meta property="og:article:author" content="MinSun" />
    </Head>
  );
}

 

// components/Layout.tsx
import Footer from "./Footer";
import Header from "./Header";
import Seo from "./Seo";

export default function Layout({ children }) {
  return (
    <main>
      <Seo />
      <Header />
      <section>
        {children}
      </section>
      <Footer />
    </main>
  );
}

 

// _app.tsx
import { useState, useEffect } from "react";
import Layout from "@/components/Layout";

export default function App({Component, pageProps: { session, ...pageProps },}) {
  return (
      <Layout>
         <Component {...pageProps} />
      </Layout>
  );
}

 

** 만약 적용안되면 next/head들을 _app.jsx로 옮기기

 

  • 다이나믹(동적) 메타 태그

Seo를 컴포넌트 화 시킨 후 각 페이지마다(pages 폴더 하위에 있는 파일 모두 다) return 바로 하위에서 불러오면 된다.해당 seo 컴포넌트는 title, desc, url, image 값이 있으면 적용한 값을 없으면 || 옆 defult 값이 적용되도록 되어있다.

 

// components/seo.tsx
import Head from "next/head";

interface SeoType {
  title: string;
  desc?: string;
  url?: string;
  image?: string;
}

export default function Seo({ title, desc, url, image }: SeoType) {
  return (
    <Head>
      <title>{title ? title : "MinSun's Blog"}</title>
      <meta name="viewport" content="initial-scale=1.0, width=device-width" />
      <meta property="og:title" content={title ? title : "MinSun's Blog"} />
      <meta property="og:site_name" content="MinSun's Blog" />
      <meta
        property="og:description"
        content={desc || "탐구한 것들을 기록하는 장소입니다."}
      />
      <meta property="og:type" content="website" />
      <meta property="og:url" content={url || "https://min-sun.vercel.app/"} />
      <meta
        property="og:image"
        content={
          image ||
          "https://images.unsplash.com/image"
        }
      />
      <meta property="og:image:width" content="1200" />
      <meta property="og:image:height" content="630" />
      <meta property="og:article:author" content="MinSun" />
    </Head>
  );
}

 

동적으로 들어오는 값들은 getServerSideProps로 받아온 데이터만 쓸 수 있다.

// index.tsx
import Seo from "@/components/seo";

export default function About() {
  return (
    <>
      <Seo title={`MinSun's Blog | About`} />
      <div>
        <div className="flex items-center justify-center gap-5 flex-col-reverse lg:flex-row">
            <p className="text-center lg:text-left">
              About
            </p>
        </div>
      </div>
    </>
  );
}


// blog/[...id].tsx
import axios from "axios";
import { NextPageContext } from "next";
import UseProperties from "libs/useProperties";
import { BASE_URL, TOKEN } from "libs/config";
import Seo from "@/components/seo";
import { useRouter } from "next/router";

export default function blockDetail({ propertiesData }: any) {
  const itemData = UseProperties(propertiesData);
	const router = useRouter();
  return (
    <>
      <Seo
        title={itemData.name}
        url={BASE_URL + "/" + router.asPath}
        desc={itemData.description}
        image={propertiesData.cover?.external.url}
      />
      <p className="text-center lg:text-left">
         blogDetail
      </p>
    </>
  );
}

export async function getServerSideProps(context: NextPageContext) {
  const { query } = context;
  const axiosConfig = {
    headers: {
      ....
    },
  };

  const responseProperties = axios.get(
    `https://api.notion.com/v1/pages/${query.id}`,
    axiosConfig
  );

  const data = responseProperties.data;
  return {
    props: {data},
  };
}

 

 

후기

동적 메타 태그적용 하면서 해맸던 점이 meta태그들이 중복으로 들어가는 문제 때문이었다.

알고 보니 정적 메타 태그에서처럼 layout에 <Seo />를 주면 안된다. layout에 선언한 <Seo />가 선언 안 한 페이지들에는 default 값으로만 이루어진 meta태그들이 들어가는 줄 알았는데 그러면 선언한 페이지 meta와 layout meta 두 개가 중복되기 때문에 layout에있는 <Seo />를 삭제 해야 한다.

 

 

meta 태그 적용 확인하는 방법

카카오 공유 디버그

 

카카오계정

 

accounts.kakao.com

url에 해당 주소 넣으면 스크랩 결과, Open Graph 정보 보여줌

만약 이미지 등 무언가를 변경했는데 적용이 안되면 캐시 초기화 후 디버그 다시하면된다.