Gatsbyダイナミックページの作成


Gatsby.jsはJAMスタックベースの静的Webサイトジェネレータです.静的サイトとは,サーバ上に存在するデータを変更せずに,ユーザに直接提示する固定的なサイト形式である.
複雑なAPI通信やバックエンドの設計に必要な作業が少ないため、純粋なJavaScriptやレスポンスを作成するだけでよいが、Gatsbyを使用する理由は、多くの有用な機能があるためかもしれない.
1つは、ダイナミックページを生成することです.この機能がない場合は、与えられたデータごとにページを1つずつ生成する必要があります.このプロセスでは、不要な重複コードが発生し、ページパスやリンクも管理されるため、非常に不便です.ただし、所定のフォーマットで自動的にページを生成する機能があれば、非常に便利です.

1.Collection Routesの使用


動的ページを作成する最初の方法は、集合ルーティング、すなわちGatsbyのファイルシステムを使用してAPIをルーティングすることである.ダイナミックページテンプレートとして使用したいコンポーネントを適切なパスに配置し、{node.field}.tsx形式でファイル名を記述します.ファイルが存在するパスとノードタイプのフィールド値に基づいてページが自動的に生成されます.
たとえば、src/pages/dictionary/{mdx.slug}.tsxがある場合、mdxタイプのノード全体に対して、そのノードインタフェース上のslug値に基づいてURLとページが生成されます.
  • /dictionary/first-info、/dctionary/son 2-bird、...
  • フィールド値が複数のアイテムの下にある場合は、{mdx.frontmatter category main}を使用して記述できます.)
  • Gatsbyでmdxファイルを処理するプラグインgatsby-plugin-mdxは、mdxタイプのノードごとにパスとファイル名を自動的に取得し、slugというフィールドを生成する.URLとして使用するのに適した値.
  • Gatsbyは、テンプレートによって作成された各ページコンポーネントに、使用するノードのidおよびfieldの値を提供する.これは、ページコンポーネントがクエリーを要求するときのクエリー変数として使用できます.
    // src/pages/blog/{mdx.slug}.js
    
    const BlogPost = ({ data }) => {
      return (
        <Layout pageTitle={data.mdx.frontmatter.title}>
          <p>{data.mdx.frontmatter.date}</p>
          <MDXRenderer>
            {data.mdx.body}
          </MDXRenderer>
        </Layout>
      )
    }
    export const query = graphql`
      query ($id: String) {
        mdx(id: {eq: $id}) {
          frontmatter {
            title
            date(formatString: "MMMM D, YYYY")
          }
          body
        }
      }
    `
    上記のコードはid値をクエリー変数として使用し、ページを作成する特定のmdxノードのデータをコンポーネントにインポートしてレンダリングします.
  • クエリー変数はページコンポーネントのクエリーでのみ使用でき、通常のコンポーネントのusStaticQuery hookでは使用できません.
  • onCreateNode API

    gatsby-plugin-mdxを使用しないか、プラグインが自動的に生成するslug値のフォーマットが気に入らない場合は、他のフィールドを使用するか、ノードごとにカスタムフィールドを追加できます.
    onCreateNodeは、Gatsbyプロジェクトの構築中にノードを作成するときに実行されます.
    // gatsby-node.js
    
    const slugify = require('slugify');
    
    exports.onCreateNode = ({ node, actions }) => {
      const { createNodeField } = actions;
    
      if (node.internal.type === `Mdx`) {
        const value = slugify(node.frontmatter.title, { lower: true });
        createNodeField({ node, name: 'slug', value });
      }
    };
    上のコードは、Mdxノードのtitle値をsluggifyライブラリに変換し、slugiと名前を付けます.」「field」フィールドの下に作成します.

    2.createPages APIの使用


    Collection routionsは便利ですが、より詳細な定義のためにページ生成関数を直接定義する必要があります.上記のコードは、すべてのmdxノードに対してページを生成するので、特定のノードをターゲットに含めたいだけです.この場合、createPagescreatePage APIを使用することができる.
    // gatsby-node.js
    
    exports.createPages = async ({ actions, graphql, reporter }) => {
      const { createPage } = actions;
    
      // category 값이 'dictionary'인 mdx 노드만 쿼리
      const query = await graphql(`
        {
          allMdx(
            filter: { frontmatter: { category: { eq: "dictionary" } } }
            sort: { order: DESC, fields: frontmatter___title }
          ) {
            edges {
              node {
                fields {
                  slug
                }
              }
            }
          }
        }
      `);
    
      if (query.errors) {
        reporter.panicOnBuild(`Error`);
        return;
      }
    
      // 템플릿 컴포넌트의 절대경로
      const TemplateComponent = path.resolve(
        __dirname,
        'src/components/main/DictionaryTemplate.tsx',
      );
    
      query.data.allMdx.edges.forEach(({
        node: {
          fields: { slug },
        },
      }) =>
        createPage({
          path: `/dictionary/${slugs}`,
          component: TemplateComponent,
          context: { slug },
        }));
    };
    ノードAPIの一種であるcreatePagesは、パラメータとしてactionsgraphql(GraphQL API)を受け入れる.ActionsはGatsby内部で使用される状態を管理するための関数の集合である.createPageという名前の関数が含まれており、生成するページURLとテンプレート要素のパスを受け入れ、contextをパラメータとして新しいページを生成します.
    上記のコードでは、createPagesの内部で必要なフォーマットのノードのみをクエリーし、createPage関数を各ノードに対して直接呼び出してページを生成します.contextオブジェクトの値(第1の方法と同様)は、テンプレートコンポーネントのpropsまたはページクエリのクエリ変数として使用することができる.
    コメントサイト
  • 反応に基づくGatsbyを用いた技術ブログの開発
  • Gatsby公式チュートリアル