LoginSignup
5

More than 1 year has passed since last update.

posted at

updated at

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

参考

学習内容

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

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

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
What you can do with signing up
5