gatsby로 블로그는 이제 대충 다 만들었는데 내가 블로그에 적은글이 검색상에 나왔으면 좋겠다!
Slug
제목을 핵심 키워드의 조합으로 간단히 만드는 방법
예를들면 포스트의 제목이 Gatsby 로 블로그 만들기 이면 그 포스트의 slug는 Gatsby-로-블로그-만들기 가 된다.
왜 slug를 써야하냐면 검색 엔진 최적화를 위해 사용한다.
slug를 사용하여 게시글 링크를 만들면 http://website/Gatsby-로-블로그-만들기 가 되기 때문에 URL을 통해 검색엔진이 더 쉽게 포스트를 찾게된다.
Gatsby에 Slug 써보기
slug도 gatsby에서 따로 제공해주는 API가 있다.
그중 onCreateNode 라는 API를 이용할것이다.
// gatsby-node.js
const path = require('path');
const { createFilePath } = require(`gatsby-source-filesystem`);
// Setup Import Alias
exports.onCreateWebpackConfig = ({ getConfig, actions }) => {
const output = getConfig().output || {};
actions.setWebpackConfig({
output,
resolve: {
alias: {
components: path.resolve(__dirname, 'src/components'),
utils: path.resolve(__dirname, 'src/utils'),
hooks: path.resolve(__dirname, 'src/hooks'),
},
},
});
};
// Generate a Slug Each Post Data
exports.onCreateNode = ({ node, getNode, actions }) => {
const { createNodeField } = actions;
if (node.internal.type === `MarkdownRemark`) {
const slug = createFilePath({ node, getNode });
createNodeField({ node, name: 'slug', value: slug });
}
};
이렇게 추가해준뒤 slug 데이터를 graphql로 확인해볼수있다.
query MyQuery {
allMarkdownRemark {
edges {
node {
fields {
slug
}
}
}
}
}
이 slug 데이터를 가지고 해당 component 를 눌렀을때 Link to={slug} 해주면 눌렀을때 해당 slug로 url이 이동하게 해준다.
그러면 해당 content 로 이동하는것은 이전에 적었던 글의 src/templates/post-template.jsx
에 이동시켜줄것이고 이 컴포넌트를 통해 patsby-node.js 파일 내에서 게시글 페이지를 생성해주는 부분이 필요하다.
// gatsby-node.js
const path = require('path');
const { createFilePath } = require(`gatsby-source-filesystem`);
// Setup Import Alias
exports.onCreateWebpackConfig = ({ getConfig, actions }) => {
const output = getConfig().output || {};
actions.setWebpackConfig({
output,
resolve: {
alias: {
components: path.resolve(__dirname, 'src/components'),
utils: path.resolve(__dirname, 'src/utils'),
hooks: path.resolve(__dirname, 'src/hooks'),
},
},
});
};
// Generate a Slug Each Post Data
exports.onCreateNode = ({ node, getNode, actions }) => {
const { createNodeField } = actions;
if (node.internal.type === `MarkdownRemark`) {
const slug = createFilePath({ node, getNode });
createNodeField({ node, name: 'slug', value: slug });
}
};
// 이부분부터 추가됨
// Generate Post Page Through Markdown Data
exports.createPages = async ({ actions, graphql, reporter }) => {
const { createPage } = actions;
// Get All Markdown File For Paging
const queryAllMarkdownData = await graphql(
`
{
allMarkdownRemark(
sort: {
order: DESC
fields: [frontmatter___date, frontmatter___title]
}
) {
edges {
node {
fields {
slug
}
}
}
}
}
`,
);
// Handling GraphQL Query Error
if (queryAllMarkdownData.errors) {
reporter.panicOnBuild(`Error while running query`);
return;
}
// Import Post Template Component
const PostTemplateComponent = path.resolve(
__dirname,
'src/templates/post_template.jsx',
);
// Page Generating Function
const generatePostPage = ({
node: {
fields: { slug },
},
}) => {
const pageOptions = {
path: slug,
component: PostTemplateComponent,
context: { slug },
};
createPage(pageOptions);
};
// Generate Post Page And Passing Slug Props for Query
queryAllMarkdownData.data.allMarkdownRemark.edges.forEach(generatePostPage);
};
};
그럼 이제 poste-template component 에서 slug에 맞는 데이터를 조회해야하는데
해당 객체에는 페이지 링크, 템플릿 컴포넌트, context의 세 가지 프로퍼티가 들어있었는데, context라는 이름으로 넘긴 객체 내의 값들은 컴포넌트에서 Props로 받을 수 있을 뿐더러 GraphQL Query의 파라미터로도 받을 수 있다고 했다.
query 내에서 사용하기 위한 파라미터 이름들은 필드 이름과 구분하기위해 $ 와 같은 접두사를 쓴다 (graphql이 원래 그렇다)
query queryMarkdownDataBySlug($slug: String) {
allMarkdownRemark(filter: { fields: { slug: { eq: $slug } } }) {
...
}
}
이렇게 쿼리를 불러오면 파라미터로 받은 slug와 일치하는 마크다운 데이터에서 필요한 값만 query 할수있다.
//post-template.jsx
query queryMarkdownDataBySlug($slug: String) {
allMarkdownRemark(filter: { fields: { slug: { eq: $slug } } }) {
edges {
node {
html
frontmatter {
title
summary
date(formatString: "YYYY.MM.DD.")
categories
thumbnail {
childImageSharp {
gatsbyImageData
}
}
}
}
}
}
}
[레퍼런스]
https://www.inflearn.com/course/gatsby-%EA%B8%B0%EC%88%A0%EB%B8%94%EB%A1%9C%EA%B7%B8
profile