Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SEO 컴포넌트 리팩토링 및 og:image 에러 수정 #31

Merged
merged 9 commits into from
Feb 16, 2023
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ SEO, 웹접근성

- [SEO, 웹 접근성](https://github.com/kimyouknow/kimyouknow.github.io/pull/15)
- [Slack에 메타 태그가 적용되지 않는 버그 수정](https://github.com/kimyouknow/kimyouknow.github.io/pull/27)
- [SEO 컴포넌트 리팩토링 및 og:image 에러 수정](https://github.com/kimyouknow/kimyouknow.github.io/pull/31)

기타

Expand Down Expand Up @@ -113,13 +114,15 @@ Github에서 아래와 같이 세팅 후 원하는 main브랜치에 push하면

```js
{
lang: "", // ko
title: ``, //Yunho.blog
author: '', // Yunho(kimyouknow)
description: ``, // 안녕하세요. 프론트엔드 개발자 김윤호입니다. 고민과 문제 해결 과정을 공유하고 있습니다.
siteUrl: '', // https://kimyouknow.github.io/
image: ``, // static 경로에 원하는 사진을 넣어주시면 프로필 이미지로 반영됩니다. ex) ./static/profile-image.png
profileImage: ``, // static 경로에 있는 사진 파일을 입력하면 프로필 이미지로 반영됩니다. ex) profile-image.png
mainOgImage :"", // static 경로에 원하는 사진 파일을 입력하면 메인페이지의 og-image 태그로 반영됩니다.
keywords: [], // 원하는 키워드를 적어주시면 keywords meta태그에 반영됩니다. ex) '개발블로그', '문제해결', 'gatsby'
favicon: '', // static 경로에 원하는 사진을 넣어주시면 favicon 이미지로 반영됩니다. ex) ./static/pencil.png
favicon: '', // static 경로에 원하는 사진을 넣어주시면 favicon 이미지로 반영됩니다. ex) /static/pencil.png
social: {
email: '', // [email protected]
github: ``, //https://github.com/kimyouknow
Expand Down
4 changes: 3 additions & 1 deletion blog-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ require('dotenv').config({
})

module.exports = {
lang: 'ko',
siteName: `Yunho.blog`,
author: 'Yunho(kimyouknow)',
description: `안녕하세요. 프론트엔드 개발자 김윤호입니다. 고민과 문제 해결 과정을 공유하고 있습니다.`,
siteUrl: 'https://kimyouknow.github.io',
image: `static/profile-image.png`,
profileImage: `profile-image.png`,
mainOgImage: 'main-og-image.png',
keywords: ['개발블로그', '문제해결', 'gatsby'],
favicon: 'static/pencil.png',
social: {
Expand Down
47 changes: 3 additions & 44 deletions src/components/Common/Image/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import styled from '@emotion/styled'
import { graphql, useStaticQuery } from 'gatsby'
import { GatsbyImage, IGatsbyImageData } from 'gatsby-plugin-image'
import { useMemo } from 'react'

import { GatsbyImageDataType } from '@/types/gatsby.type'
import useStaticImage from '@/hooks/useStaticImage'

const ImageSizeMap = {
s: 'var(--icon-medium)',
Expand All @@ -19,36 +17,14 @@ interface ImageProps {
isCircle?: boolean
}

interface ImageNode {
node: {
relativePath: string
extension: string
publicURL: string
childImageSharp: {
gatsbyImageData: IGatsbyImageData
}
}
}

interface AssetsImageType {
images: {
edges: ImageNode[]
}
}

interface GatsbyImgProps extends Omit<ImageProps, 'src'> {
image: GatsbyImageDataType
image: IGatsbyImageData
alt: string
className?: string
}

const Image = ({ src, size = 'm', isCircle = false, ...rest }: ImageProps) => {
const assetImages = useStaticQuery<AssetsImageType>(imageQuery)

const target = useMemo(
() => assetImages.images.edges.find(({ node }) => src === node.relativePath),
[assetImages, src],
)
const target = useStaticImage({ src })

if (!target) return null

Expand All @@ -70,20 +46,3 @@ const SImage = styled(({ isCircle, ...rest }: GatsbyImgProps) => <GatsbyImage {.
`

export default Image

const imageQuery = graphql`
query {
images: allFile(filter: { sourceInstanceName: { eq: "static" } }) {
edges {
node {
relativePath
extension
publicURL
childImageSharp {
gatsbyImageData(layout: CONSTRAINED)
}
}
}
}
}
`
6 changes: 2 additions & 4 deletions src/components/PostDetail/PostDetail.style.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import styled from '@emotion/styled'
import { GatsbyImage } from 'gatsby-plugin-image'

import { GatsbyImageDataType } from '@/types/gatsby.type'
import { GatsbyImage, IGatsbyImageData } from 'gatsby-plugin-image'

// Header
interface GatsbyImgProps {
image: GatsbyImageDataType
image: IGatsbyImageData
alt: string
className?: string
}
Expand Down
4 changes: 2 additions & 2 deletions src/components/PostDetail/PostHeader/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { GatsbyImageDataType } from '@/types/gatsby.type'
import { IGatsbyImageData } from 'gatsby-plugin-image'

import * as S from '../PostDetail.style'
import PostHeaderInfo, { PostHeadInfoProps } from './PostHeader.info'

interface PostHeaderProps extends PostHeadInfoProps {
thumbnail: GatsbyImageDataType
thumbnail: IGatsbyImageData
}

const PostHeader = ({ title, date, categories, thumbnail, readingTime }: PostHeaderProps) => {
Expand Down
12 changes: 3 additions & 9 deletions src/components/PostDetail/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import PostFooter from '@/components/PostDetail/PostFooter'
import SEO from '@/components/SEO'
import useBlogConfig from '@/hooks/useBlogConfig'
import Layout from '@/Layout'
import { PostPageItemType } from '@/types/PostItem.types'

Expand All @@ -9,11 +8,10 @@ import PostHeader from './PostHeader'

interface PostPageInfoProps {
postPageInfo: PostPageItemType
href: string
pathname: string
}

const PostDetail = ({ postPageInfo, href }: PostPageInfoProps) => {
const { author, favicon, seo, siteName } = useBlogConfig()
const PostDetail = ({ postPageInfo, pathname }: PostPageInfoProps) => {
const {
node: {
tableOfContents,
Expand All @@ -34,15 +32,11 @@ const PostDetail = ({ postPageInfo, href }: PostPageInfoProps) => {
return (
<Layout>
<SEO
author={author}
siteUrl={href}
siteName={siteName}
title={title}
pathname={pathname}
description={summary}
image={publicURL}
keywords={categories}
favicon={favicon}
seo={seo}
readingTime={readingTime.text}
/>
<PostHeader
Expand Down
40 changes: 28 additions & 12 deletions src/components/SEO/index.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,37 @@
import { Helmet } from 'react-helmet'

import useBlogConfig from '@/hooks/useBlogConfig'
import useStaticImage from '@/hooks/useStaticImage'
import { SEOConfigType } from '@/types/gatsby.type'

const SEO = ({
lang = 'ko',
author,
siteName,
siteUrl,
title = siteName,
// 변동
title,
pathname,
description,
image,
keywords,
favicon,
seo,
readingTime,
}: SEOConfigType) => {
const absoluteImagePath = `${siteUrl}/${image}`
const {
lang,
author,
siteName,
favicon,
seo,
siteUrl,
mainOgImage,
description: mainDesc,
keywords: mainKeywords,
} = useBlogConfig()
const target = useStaticImage({ src: mainOgImage })
const mainOgImagePath = target?.node.publicURL || ''
// params가 없으면 기본 config type을 사용하기
const pageUrl = `${siteUrl}${pathname || ``}`
keywords = keywords || mainKeywords
description = description || mainDesc
image = image ? `${siteUrl}${image}` : `${siteUrl}/${mainOgImagePath}`
title = title || siteName
return (
<Helmet htmlAttributes={{ lang }}>
<title>{title}</title>
Expand All @@ -31,16 +47,16 @@ const SEO = ({
<meta property="og:site_name" content={siteName} />
<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
<meta property="og:image" content={absoluteImagePath} />
<meta property="og:url" content={siteUrl} />
<meta property="og:image" content={image} />
<meta property="og:url" content={pageUrl} />
<meta property="og:locale" content="ko_KR" />
<meta property="og:locale:alternate" content="es_ES" />
{/* twitter cards tags additive with th og: tags */}
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:domain" content={siteUrl} />
<meta name="twitter:domain" content={pageUrl} />
<meta name="twitter:title" content={title} />
<meta name="twitter:description" content={description} />
<meta name="twitter:image" content={absoluteImagePath} />
<meta name="twitter:image" content={image} />
<meta name="twitter:image:alt" content={description} />
<meta name="twitter:label1" content="Time to read" />
<meta name="twitter:data1" content={readingTime} />
Expand Down
3 changes: 2 additions & 1 deletion src/hooks/useBlogConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ const useBlogConfig = () => {
siteName
description
siteUrl
image
profileImage
mainOgImage
keywords
favicon
social {
Expand Down
54 changes: 54 additions & 0 deletions src/hooks/useStaticImage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { graphql, useStaticQuery } from 'gatsby'
import { IGatsbyImageData } from 'gatsby-plugin-image'
import { useMemo } from 'react'

interface ImageNode {
node: {
relativePath: string
extension: string
publicURL: string
childImageSharp: {
gatsbyImageData: IGatsbyImageData
}
}
}

interface AssetsImageType {
images: {
edges: ImageNode[]
}
}

export interface useStaticImageProps {
src: string
}

const useStaticImage = ({ src }: useStaticImageProps) => {
const assetImages = useStaticQuery<AssetsImageType>(imageQuery)

const target = useMemo(
() => assetImages.images.edges.find(({ node }) => src === node.relativePath),
[assetImages, src],
)

return target
}

export default useStaticImage

const imageQuery = graphql`
query {
images: allFile(filter: { sourceInstanceName: { eq: "static" } }) {
edges {
node {
relativePath
extension
publicURL
childImageSharp {
gatsbyImageData(layout: CONSTRAINED)
}
}
}
}
}
`
13 changes: 1 addition & 12 deletions src/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import MainHeader from '@/components/CategoryHeader'
import { CategoryListProps } from '@/components/CategoryHeader/CategoryList'
import PostList from '@/components/PostList'
import SEO from '@/components/SEO'
import useBlogConfig from '@/hooks/useBlogConfig'
import Layout from '@/Layout'
import { PostListItemType, PostType } from '@/types/PostItem.types'

Expand All @@ -27,7 +26,6 @@ const IndexPage = ({
allMarkdownRemark: { edges },
},
}: IndexPageProps) => {
const { author, siteName, siteUrl, description, image, keywords, favicon, seo } = useBlogConfig()
const parsed: ParsedQuery<string> = queryString.parse(hash)
const selectedCategory = typeof parsed.category !== 'string' || !parsed.category ? 'All' : parsed.category
// category 프로퍼티 값이 문자열 형태가 아니거나 존재하지 않는 경우에는 기본적으로 카테고리 값을 All로 지정하고, 그러지 않은 경우에는 파싱한 값을 지정
Expand Down Expand Up @@ -57,16 +55,7 @@ const IndexPage = ({
)
return (
<Layout>
<SEO
author={author}
siteUrl={siteUrl}
siteName={siteName}
description={description}
image={image}
keywords={keywords}
favicon={favicon}
seo={seo}
/>
<SEO />
<MainHeader selectedCategory={selectedCategory} categoryList={categoryList} />
<PostList selectedCategory={selectedCategory} posts={edges} />
</Layout>
Expand Down
6 changes: 3 additions & 3 deletions src/templates/post.template.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,17 @@ interface PostTemplateProps {
}
}
location: {
href: string
pathname: string
}
}

const PostTemplate = ({
data: {
allMarkdownRemark: { edges },
},
location: { href },
location: { pathname },
}: PostTemplateProps) => {
return <PostDetail postPageInfo={edges[0]} href={href} />
return <PostDetail postPageInfo={edges[0]} pathname={pathname} />
}

export default PostTemplate
Expand Down
4 changes: 2 additions & 2 deletions src/types/PostItem.types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { GatsbyImageDataType } from './gatsby.type'
import { IGatsbyImageData } from 'gatsby-plugin-image'

export interface PostFrontmatterType {
title: string
Expand All @@ -7,7 +7,7 @@ export interface PostFrontmatterType {
summary: string
thumbnail: {
childImageSharp: {
gatsbyImageData: GatsbyImageDataType
gatsbyImageData: IGatsbyImageData
}
publicURL: string
}
Expand Down
Loading