11
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Gatsbyノート3(slug/pageの生成)

Last updated at Posted at 2020-09-06

参考

学習内容

  • ブログの詳細ページを作成する

1.前提

slugとは

URL(パーマリンク)の末尾の部分を任意の文字列に指定できる機能で、URLの一部になる
英数字、アンダースコア、ハイフンからなる短いラベル文字列

onCreateNodeとは

Gatsbyで各nodeが生成されるタイミングでnodeにデータを追加し、nodeの再編成をすることができる

  • 詳細ページへのslugを生成する
  • 作成したslugをnodeに追加する
  • gatsby-node.jsに処理を追加する
sample.js

exports.onCreateNode = ({ node, actions }) => {
  const { createNode, createNodeField } = actions
  // Transform the new node here and create a new node or
  // create a new node field.
}

basename関数(Slugの抽出)とは

sample.js

path.basename('/foo/bar/baz/asdf/quux.html', '.html');
// Returns: 'quux'

createNodeFieldとは

sample.js

createNodeField({
  node,
  name: `happiness`,
  value: `is sweet graphql queries`
})

createPages(ページの生成)とは

2.gatsby-node.jsでslugとpageの生成

gatsby-node.js

const path = require('path');

//slugの生成
module.exports.onCreateNode = ({ node, actions }) => {
    const { createNodeField } = actions
    //MarkdownRemarkの場合に、slugを追加する
    if(node.internal.type === 'MarkdownRemark') {
        //node.jsのbasename関数を用いてslugを抽出
        const slug = path.basename(node.fileAbsolutePath, '.md')
        
        //nodeの再編成 createNodeField: https://www.gatsbyjs.com/docs/reference/config-files/actions/#createNodeField  
        createNodeField({
            node,
            name: 'slug',
            value: slug
        })
    }
}

//ページの生成
module.exports.createPages = async ({ graphql, actions }) => {
    const { createPage } = actions
    //ブログ詳細ページ用のテンプレートの取得
    const blogTemplate = path.resolve('./src/templates/blogDetail.js')
    const res = await graphql(`
        query {
            allMarkdownRemark {
                edges {
                    node {
                        fields {
                            slug
                        }
                    }
                }
            }
        }
    `)
    //各ページの生成
    res.data.allMarkdownRemark.edges.forEach((edge) => {
        createPage({
            component: blogTemplate,
            path: `/blog/${edge.node.fields.slug}`,
            context: {
                slug: edge.node.fields.slug
            }
        })
    })
}

3.各ページでslugを利用する

index.js

index.js

import React from "react"
import { graphql, useStaticQuery } from "gatsby"
import Layout from "../components/layout"
import Kv from "../components/kv"
import BlogItem from "../components/blogItem"
import {Container, Row, Col} from 'react-bootstrap'

const IndexPage = () => {
//slug追加
  const data = useStaticQuery(graphql`
    query {
      allMarkdownRemark {
        edges {
          node {
            fields {
              slug
            }
            frontmatter {
              date
              title
              thumbnail {
                childImageSharp {
                  fluid {
                    src
                  }
                }
              }
            }
          }
        }
      }
    }
  `)
  return (
    <Layout>
      <Kv />
      <Container>
        <Row>
          {
            data.allMarkdownRemark.edges.map((edge, index) => (
              <Col sm={4} key={index}>
                <BlogItem
                  title={edge.node.frontmatter.title}
                  date={edge.node.frontmatter.date}
                  src={edge.node.frontmatter.thumbnail.childImageSharp.fluid.src}
//slug追加
                  link={`blog/${edge.node.fields.slug}`} />
              </Col>
            ))
          }
        </Row>
      </Container>
    </Layout>
  )
}

export default IndexPage

blogItem.js

blogItem.js

import React from 'react'
import { Card } from 'react-bootstrap'
import { Link } from 'gatsby'

function BlogItem({title, date, src, link}) {
    return (
       <Card className="mt-4">
           <Card.Img variant="" src={src} />
           <Card.Body>
                <Card.Title>{title}</Card.Title>
                <Card.Text>
                    {date}
                </Card.Text>
                <Link to={`/${link}`}>see more</Link>
           </Card.Body>
       </Card>
    )
}

export default BlogItem
11
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?