Jisoo.

기술블로그

Open Graph Protocol란 무엇일까


썸네일

Open Graph Protocol

Open Graph Protocol에 대해 알아보고 블로그에 적용해 보겠습니다.

2010년 페이스북이 발표한 인터넷 프로토콜의 일종으로 HTML Meta 태그를 이용하여 해당 페이지의 미리보기를 제공하는 기술입니다.

그래프(Graph)라는 용어는 소셜 네트워크를 표시하는 방식으로 각 노드는 객체(사람, 웹 페이지, 제품)를 의미하고 엣지는 그 객체 간의 관계를 의미하는 것입니다.

Open Graph는 이 노드(웹 페이지)가 다른 노드와 어떻게 연결되는지를 나타내는 메타 데이터를 제공합니다.


💡 왜 사용하는가

1. 사용자 유입 증가

소셜 미디어는 유저의 컨텐츠가 더 많은 사람에게 멀리 퍼지는 것을 중요시합니다.

Open Graph를 이용한다면 해당 페이지의 콘텐츠를 미리 볼 수 있기 때문에 사용자의 흥미를 이끌어 클릭할 가능성이 높아지므로 소셜 미디어 트래픽이 많아지는 효과를 기대할 수 있습니다.

2. 검색 엔진 최적화(SEO)

검색 엔진 최적화는 다른 사용자가 자신의 콘텐츠를 발견하기 쉽게 도와주는 검색 엔진에 맞춰 콘텐츠를 제공하는 것을 의미합니다.

구글 SEO 기본 가이드

검색 엔진은 HTML meta description 태그를 읽어 들여 해당 페이지가 어떤 주제를 나타내는지 이해하므로 구글에서는 해당 태그를 잘 작성하는 것을 권고하고 있습니다.

직접적으로 Open Graph가 SEO에 도움이 된다고 볼 수 없지만, 미리보기를 제공할 경우 해당 페이지를 클릭할 가능성이 높아지는데, 클릭률(CTR, Click Through Rate)이 증가할 경우 검색 엔진은 해당 페이지를 유용한 페이지로 판단할 수 있습니다.

따라서 노출 순위가 중요한 브랜드 마케팅, 광고 산업에서는 Open Graph가 중요할 수 있습니다.


💡 Open Graph Protocol 사용법

보여주려는 웹 페이지(html)에서 <head> 태그 내부에 <meta> 태그를 배치합니다.

이때, og:로 시작하는 프로퍼티와 값을 추가할 수 있습니다.

1<html prefix="og: https://ogp.me/ns#"> 2<head> 3<title>The Rock (1996)</title> 4<meta property="og:title" content="The Rock" /> 5<meta property="og:type" content="video.movie" /> 6<meta property="og:url" content="https://www.imdb.com/title/tt0117500/" /> 7<meta property="og:image" content="https://ia.media-imdb.com/images/rock.jpg" /> 8... 9</head> 10... 11</html>

💡 OPG 프로퍼티

Open Graph의 값은 Boolean, DateTime, Enum, Float, Int, String, URL 형식을 지원합니다.

또한 각 프로퍼티는 구조화(Structured)되어 추가 프로퍼티를 가질 수 있습니다.

예를 들어 image 프로퍼티는 추가 메타 데이터를 가질 수 있습니다.

1<meta property="og:image" content="https://example.com/ogp.jpg" /> 2<meta property="og:image:secure_url" content="https://secure.example.com/ogp.jpg" /> 3<meta property="og:image:type" content="image/jpeg" /> 4<meta property="og:image:width" content="400" /> 5<meta property="og:image:height" content="300" /> 6<meta property="og:image:alt" content="A shiny red apple with a bite taken out" />

이는 다음과 같습니다.

1const image = { 2 url : "https://example.com/ogp.jpg" 3 secureUrl : "https://secure.example.com/ogp.jpg" 4 type : "image/jpeg" 5 width : 400 6 height : 300 7 alt : ... 8}

또한 하나의 프로퍼티는 여러 값을 가질 수 있습니다.

1# 300 X 300 이미지 2<meta property="og:image" content="https://example.com/rock.jpg" /> 3<meta property="og:image:width" content="300" /> 4<meta property="og:image:height" content="300" /> 5 6# 크기가 지정되지 않은 이미지 7<meta property="og:image" content="https://example.com/rock2.jpg" /> 8 9# 1000px 이미지 10<meta property="og:image" content="https://example.com/rock3.jpg" /> 11<meta property="og:image:height" content="1000" />

값이 충돌할 경우 더 위에 있는 태그를 우선으로 출력합니다.

- 필수 프로퍼티

공식 문서에서는 다음 4가지 프로퍼티를 필수로 규정합니다.

속성설명추가 속성
og:title해당 웹 페이지의 제목
og:type유형 (video, article 등)
og:;image이미지 URLurl, secure_url, type, width, height, alt
og:url웹 페이지 URL ( = 객체의 ID )

og:type의 경우 music.song, video.movie, article, book, profile, website 등 정해진 값(enum)을 사용해야합니다.

- 선택 프로퍼티

속성설명추가 속성
og:audio오디오 URLurl, secure_url, type
og:video비디오 URLurl, secure_url, type, width, height, alt
og:description웹 페이지에 대한 짧은 설명
og:determiner웹 페이지 제목의 관사(A, The, ...)
og: locale해당 페이지의 언어 형식
og:site_name해당 웹 사이트의 전체 이름

💡 더 알아보기

- RDF

Open Graph Protocol은 웹 페이지를 하나의 객체로 정의합니다.

각각의 메타 태그는 RDF(Resource Description Framework)로 표현할 수 있습니다.

RDF는 데이터를 구조화하는 데 사용되는 표준 모델로써 주로 웹 상에서 컴퓨터가 데이터를 이해할 수 있게 정의하는 기법입니다.

Open Graph Protocol RDF 스키마

1og:url a rdf:Property ; 2 rdfs:label "url"@en-US ; 3 rdfs:comment "..." ; 4 rdfs:seeAlso dc:identifier, 5 foaf:homepage ; 6 rdfs:isDefinedBy og: ; 7 rdfs:range ogc:url .

💡 블로그에 적용해 보기

제 블로그는 NextJS 14.2.7 버전으로 만들었기 때문에 NextJS에서 제공하는 메타데이터 기능을 사용하여 OPG를 구현해 보겠습니다.

NextJS Metadata Docs

- 정적 Metadata 정의하기

NextJS에서는 Metadata 인터페이스를 제공하며 App Router 기준 layout 또는 page에서 선언하여 사용할 수 있습니다.

1// layout.tsx 2export const metadata: Metadata = { 3 title: "남지수 기술 블로그", 4 description: "주니어 프론트 개발자의 성장 일지 | 개발 관련 기록", 5 keywords: ["프론트엔드", "기술 블로그", "개발", "기록", "자기계발"], 6 metadataBase: new URL(`${process.env.SERVER_URL}`), 7 verification: { google: "구글 서치 콘솔 인증 키" }, 8 openGraph: { 9 type: "article", 10 images: [ 11 { 12 url: "/thumbnails/geranimo-bKhETeDV1WM-unsplash.webp", 13 }, 14 ], 15 }, 16};

metadata를 최상단 layout.tsx에 정의하여 모든 페이지에서 해당 메타데이터를 사용 하였습니다.

- 동적 Metadata 정의하기

블로그 같은 경우에는 해당 글의 제목, 내용, 썸네일 등을 보여주는 게 효과적이라고 볼 수 있습니다.

따라서 글마다 메타데이터가 동적으로 바뀌어야 합니다.

NextJS에서는 서버 페이지에서 generateMetadata() 함수를 제공하여 동적으로 메타데이터를 선언할 수 있습니다.

제 블로그에서는 /post에서 특정 포스트에 대한 정보를 가져오기 때문에 해당 라우터 페이지에서 함수를 작성해 보겠습니다.

1// src/app/post/[slug]/page.tsx 2type MetaProps = { 3 params: Params; 4 searchParams: { [key: string]: string | string[] | undefined }; 5}; 6 7export async function generateMetadata( 8 { params }: MetaProps, 9 parent: ResolvingMetadata 10): Promise<Metadata> { 11 const slug = params.slug; 12 13 // title로 해당 post 객체를 불러오는 함수입니다. 14 // prisma.post.findFirst... 15 const post = await getPostByTitle( 16 decodeURIComponent(params.slug.replace(/-/g, " ")) 17 ); 18 19 const previousImages = (await parent).openGraph?.images || []; 20 21 return { 22 title: post?.title, 23 openGraph: { 24 title: post?.title, 25 type: "article", 26 description: post?.description, 27 images: [post?.thumbnail?.path ?? "", ...previousImages], 28 url: `/post/${post?.title}`, 29 }, 30 }; 31}

적용 후 DevTools에서 HTML을 확인해 보았습니다.

1<meta name="viewport" content="width=device-width, initial-scale=1"> 2<meta charset="utf-8"> 3<title>1. Docker 란 무엇일까</title> 4<meta name="description" content="주니어 프론트 개발자의 성장 일지 | 개발 관련 기록"> 5<meta name="keywords" content="프론트엔드,기술 블로그,개발,기록,자기계발"> 6 7<meta property="og:title" content="1. Docker 란 무엇일까"> 8<meta property="og:description" content="Docker에 대해서 간단하게 알아봅시다."> 9<meta property="og:url" content="http://localhost:3000/post/1.%20Docker%20%EB%9E%80%20%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C"> 10<meta property="og:image" content="http://localhost:3000/thumbnails/docker.webp"> 11<meta property="og:image" content="http://localhost:3000/thumbnails/geranimo-bKhETeDV1WM-unsplash.webp"><meta property="og:type" content="article"> 12 13<meta name="twitter:card" content="summary_large_image"> 14<meta name="twitter:title" content="1. Docker 란 무엇일까"> 15<meta name="twitter:description" content="Docker에 대해서 간단하게 알아봅시다."> 16<meta name="twitter:image" content="http://localhost:3000/thumbnails/docker.webp"> 17<meta name="twitter:image" content="http://localhost:3000/thumbnails/geranimo-bKhETeDV1WM-unsplash.webp"> 18

잘 적용되었으니, 카카오톡에서 실제로 출력해 보겠습니다.

글 이미지

임의로 블로그 글을 링크했을 때, 기존에는 블로그 제목과 글과 관련 없는 이미지가 출력되었다면

OGP을 적용한 뒤에는 해당 글의 썸네일, 제목, 설명이 출력되는 것을 확인할 수 있습니다.

카카오톡의 경우 URL에 해당하는 Open Graph를 서버에 캐시로 저장하기 때문에 공유 디버거를 통해 캐시 초기화를 해주어야 변경 사항이 적용됩니다.

카카오톡 공유 디버거


💡 마무리

Open Graph Protocol에 대하여 알아보고 실제로 블로그에 적용해 보았습니다.

실제로 적용해 보니 글과 관련된 미리보기를 제공하니 더 클릭해 보고 싶어지지 않을까 싶습니다.


1


관련 포스트

썸네일-0

웹 성능 지표 TTI, TTV에 대해서 알아보기

TTI, TTV에 대해서 알아봅시다.


2024년 10월 14일