개요
일상 속에서 카카오톡이나 기타 메신저들을 사용하여 링크를 공유해본 경험이 다들 존재할 것이다.
링크를 공유할시 페이지의 썸네일과 간단한 정보들이 담기는걸 본 적이 있을텐데 이러한 기능은 SEO적인 측면에서 큰 도움이 된다.
Open Graph
Open Graph
오픈 그래프(Open Graph) 란 HTML 의 meta 태그 중 og:XXX 형태의 태그를 찾아서 웹 페이지를 공유할 때 이용자가 더욱 자세한 정보들을 얻을 수 있게 해주는 프로토콜의 일종이다.
적용법
오픈 그래프를 적용하는 법은 생각보다 간단하다. HTML 의 head 영역에 오픈그래프가 요구하는 meta 태그 형식만 맞추어서 삽입하면 된다.
1 import { DOMAIN , DOMAIN_KOR } from "@/constants/domain"
2 import PageType from "@/types/page"
3 import Post from "@/types/post"
4 import Head from "next/head"
5 import { useRouter } from "next/router"
6
7 type Props = {
8 post ? : Post ,
9 page : PageType ,
10 }
11
12 type MetaDataType = {
13 title : string ,
14 url : string ,
15 image ? : string ,
16 desc ? : string ,
17 }
18
19 type ctxType = {
20 category ? : string ,
21 slug ? : string ,
22 tag ? : string ,
23 }
24
25 const getMetaData = ( pageType : PageType , ctx : ctxType , post ? : Post ) : MetaDataType => {
26 const { category , slug , tag } = ctx ;
27 const BASIC_THUMBNAIL = '/assets/seo/meta_thumbnail.png'
28 const metaData = {
29 title : '' ,
30 url : '' ,
31 desc : '' ,
32 image : BASIC_THUMBNAIL
33 } ;
34
35 switch ( pageType ) {
36 case PageType . Post :
37 if ( ! post ) break ;
38 metaData . title = ` ${ post ?. title } | ${ DOMAIN } ` ,
39 metaData . url = ` ${ DOMAIN } /post/? ${ category } / ${ slug } ` ;
40 metaData . desc = post . description ;
41 metaData . image = post . thumbnail ;
42 break ;
43 case PageType . Main :
44 metaData . title = ` ${ DOMAIN_KOR } | ${ DOMAIN } ` ,
45 metaData . url = ` ${ DOMAIN } ` ;
46 metaData . desc = ` ${ DOMAIN_KOR } 입니다 ` ;
47 break ;
48 case PageType . Category :
49 metaData . title = ` ${ category } | ${ DOMAIN } ` ;
50 metaData . url = ` ${ DOMAIN } /category/ ${ category } ` ;
51 metaData . desc = ` ${ category } Category Posts ` ;
52 break ;
53 case PageType . Tags :
54 metaData . title = ` Tags | ${ DOMAIN } ` ;
55 metaData . url = ` ${ DOMAIN } /tags ` ;
56 metaData . desc = ` Tags List ` ;
57 break ;
58 case PageType . Tag :
59 metaData . title = ` ${ tag } | ${ DOMAIN } ` ;
60 metaData . url = ` ${ DOMAIN } /tags/ ${ tag } ` ;
61 metaData . desc = ` ${ tag } Tag Posts ` ;
62 break ;
63 case PageType . About :
64 metaData . title = ` About | ${ DOMAIN } ` ;
65 metaData . url = ` ${ DOMAIN } /about ` ;
66 metaData . desc = 'About Myself' ;
67 break ;
68 }
69
70 return metaData ;
71 }
72
73 const SeoHead = ( { post , page } : Props ) => {
74 const router = useRouter ( ) ;
75 const metaData = getMetaData ( page , router . query , post ) ;
76
77 return (
78 < Head >
79 < link rel = "apple-touch-icon" sizes = "57x57" href = "/assets/seo/favicons/apple-icon-57x57.png" > < / link >
80 < link rel = "apple-touch-icon" sizes = "60x60" href = "/assets/seo/favicons/apple-icon-60x60.png" > < / link >
81 < link rel = "apple-touch-icon" sizes = "72x72" href = "/assets/seo/favicons/apple-icon-72x72.png" > < / link >
82 < link rel = "apple-touch-icon" sizes = "76x76" href = "/assets/seo/favicons/apple-icon-76x76.png" > < / link >
83 < link rel = "apple-touch-icon" sizes = "114x114" href = "/assets/seo/favicons/apple-icon-114x114.png" > < / link >
84 < link rel = "apple-touch-icon" sizes = "120x120" href = "/assets/seo/favicons/apple-icon-120x120.png" > < / link >
85 < link rel = "apple-touch-icon" sizes = "144x144" href = "/assets/seo/favicons/apple-icon-144x144.png" > < / link >
86 < link rel = "apple-touch-icon" sizes = "152x152" href = "/assets/seo/favicons/apple-icon-152x152.png" > < / link >
87 < link rel = "apple-touch-icon" sizes = "180x180" href = "/assets/seo/favicons/apple-icon-180x180.png" > < / link >
88 < link rel = "icon" type = "image/png" sizes = "192x192" href = "/assets/seo/favicons/android-icon-192x192.png" > < / link >
89 < link rel = "icon" type = "image/png" sizes = "32x32" href = "/assets/seo/favicons/favicon-32x32.png" > < / link >
90 < link rel = "icon" type = "image/png" sizes = "96x96" href = "/assets/seo/favicons/favicon-96x96.png" > < / link >
91 < link rel = "icon" type = "image/png" sizes = "16x16" href = "/assets/seo/favicons/favicon-16x16.png" > < / link >
92 < link rel = "icon" href = "/assets/seo/favicons/favicon.ico" / >
93 < meta name = "msapplication-TileColor" content = "#2A2A2A" / >
94 < meta name = "msapplication-TileImage" content = "/ms-icon-144x144.png" / >
95 < meta name = "theme-color" content = "#2A2A2A" / >
96 < meta property = "og:title" content = { metaData . title } / >
97 < meta property = "og:url" content = { metaData . url } / >
98 < meta property = "og:image" content = { metaData . image } / >
99 < meta
100 property = "og:description"
101 content = { metaData . desc }
102 / >
103 < meta name = "twitter:card" content = "summary" / >
104 < meta property = "twitter:domain" content = { DOMAIN } / >
105 < meta property = "twitter:url" content = { metaData . url } / >
106 < meta name = "twitter:title" content = { metaData . title } / >
107 < meta name = "twitter:description" content = { metaData . desc } / >
108 < meta name = "twitter:image" content = { metaData . image } / >
109 < meta
110 name = "description"
111 content = { metaData . desc }
112 / >
113 < title > { metaData . title } < / title >
114 < / Head >
115 )
116 }
117
118 export default SeoHead ;
119
1 < meta property = " og:title " content = " {metaData.title} " />
2 < meta property = " og:url " content = " {metaData.url} " />
3 < meta property = " og:image " content = " {metaData.image} " />
4 < meta property = " og:description " content = " {metaData.desc} " />
5 < meta name = " twitter:card " content = " summary " />
6 < meta property = " twitter:domain " content = " {DOMAIN} " />
7 < meta property = " twitter:url " content = " {metaData.url} " />
8 < meta name = " twitter:title " content = " {metaData.title} " />
9 < meta name = " twitter:description " content = " {metaData.desc} " />
10 < meta name = " twitter:image " content = " {metaData.image} " />
11
오픈 그래프에는 여러가지 어트리뷰트 옵션이 있지만 위와 같은 기본사항만 입력해줘도 충분히 멋진 결과물을 얻을 수 있다.
content 어트리뷰트에는 각자 알맞은 값들을 할당해주면 된다.
썸네일 이미지 같은 경우에는 1200*630px 해상도가 권장된다.
나는 페이지별로 content 영역을 다르게 표현해주고 싶어서 페이지에 따른 메타데이터를 반환하는 함수를 따로 분리하였다.
1 const getMetaData = ( pageType : PageType , ctx : ctxType , post ? : Post ) : MetaDataType => {
2 const { category , slug , tag } = ctx ;
3 const BASIC_THUMBNAIL = '/assets/seo/meta_thumbnail.png' ;
4 const metaData = {
5 title : '' ,
6 url : '' ,
7 desc : '' ,
8 image : BASIC_THUMBNAIL ,
9 } ;
10
11 switch ( pageType ) {
12 case PageType . Post :
13 if ( ! post ) break ;
14 ( metaData . title = ` ${ post ?. title } | ${ DOMAIN } ` ) , ( metaData . url = ` ${ DOMAIN } /post/? ${ category } / ${ slug } ` ) ;
15 metaData . desc = post . description ;
16 metaData . image = post . thumbnail ;
17 break ;
18 case PageType . Main :
19 ( metaData . title = ` ${ DOMAIN_KOR } | ${ DOMAIN } ` ) , ( metaData . url = ` ${ DOMAIN } ` ) ;
20 metaData . desc = ` ${ DOMAIN_KOR } 입니다 ` ;
21 break ;
22 case PageType . Category :
23 metaData . title = ` ${ category } | ${ DOMAIN } ` ;
24 metaData . url = ` ${ DOMAIN } /category/ ${ category } ` ;
25 metaData . desc = ` ${ category } Category Posts ` ;
26 break ;
27 case PageType . Tags :
28 metaData . title = ` Tags | ${ DOMAIN } ` ;
29 metaData . url = ` ${ DOMAIN } /tags ` ;
30 metaData . desc = ` Tags List ` ;
31 break ;
32 case PageType . Tag :
33 metaData . title = ` ${ tag } | ${ DOMAIN } ` ;
34 metaData . url = ` ${ DOMAIN } /tags/ ${ tag } ` ;
35 metaData . desc = ` ${ tag } Tag Posts ` ;
36 break ;
37 case PageType . About :
38 metaData . title = ` About | ${ DOMAIN } ` ;
39 metaData . url = ` ${ DOMAIN } /about ` ;
40 metaData . desc = 'About Myself' ;
41 break ;
42 }
43
44 return metaData ;
45 } ;
46
결과
메인 페이지
포스트 페이지
게다가 오픈 그래프의 적용 여부를 테스트해주는 사이트 또한 존재한다.
favicon
파비콘은 브라우저의 주소창에 표시되는 웹페이지를 대표하는 아이콘이다.
간단한 아이콘을 추가하여 유저에게 사이트에 대한 이미지를 심어줄 수 있다.
유명 기업의 favicons
favicon generator
이러한 favicon들을 브라우저가 요구하는 양식에 맞춰 자동으로 생성해주는 사이트 가 있다.
192*192px의 png 파일을 업로드하면 다양한 양식의 아이콘 이미지 파일과 태그들을 출력해준다.
세상엔 좋은 사이트들이 참 많습니다
결과
favicon이 적용된 모습