チュートリアル: JSS Next.js アプリでのビルド時の静的パスのカスタマイズ

Version: 20.x
日本語翻訳に関する免責事項

このページの翻訳はAIによって自動的に行われました。可能な限り正確な翻訳を心掛けていますが、原文と異なる表現や解釈が含まれる場合があります。正確で公式な情報については、必ず英語の原文をご参照ください。

数多くのページ、製品、記事を持つ非常に大きな Web サイトでは、すべてのページのための静的生成に長い時間がかかる場合があります。静的に生成されるアプリケーションのビルド時間を短縮するには、一部のタイプのページやアイテムを静的生成から除外します。

これを行うには、getStaticPaths 関数でカスタマイズした sitemap-fetcher を使用し、ビルド時に静的に生成されるページのリストを変更します。

このチュートリアルでは、以下の方法について説明します。

  • カスタム サイトマップ サービスを作成します。

  • 静的パスのリストをカスタマイズするには、カスタム サイトマップ フェッチャーを作成します。

カスタム サイトマップ サービスを作成する

GraphQLSitemapService クラスと GraphQLSitemapServiceConfig インターフェイスを拡張して、特定のアイテム タイプを除外できます。

  1. src/lib で新しいファイル sitemap-service.ts を作成します。

  2. 新しいファイルで、Sitecore Next.js SDK から GraphQLSitemapService クラスと GraphQLSitemapServiceConfig インターフェイスをインポートします。

    RequestResponse
      import {
        GraphQLSitemapService,
        GraphQLSitemapServiceConfig,
      } from '@sitecore-jss/sitecore-jss-nextjs';
  3. GraphQLSitemapServiceConfig を拡張し、追加のオプションをサービス設定に追加します。

    RequestResponse
      export interface ExtendedSitemapServiceConfig extends GraphQLSitemapServiceConfig {
        /**
        * Item with sub-paths to exclude
        */
    
        excludeItemId?: string;
      }
  4. Sitecore Delivery Edge では、検索クエリに有効な ID が必要です。excludeItemId オプションを使用しない場合については、有効で空の ID を指定する必要があります。emptyID 定数を次のように宣言します。

    RequestResponse
    const emptyId = '{00000000-0000-0000-0000-000000000000}';
  5. GraphQLSitemapService クラスを拡張し、query ゲッターを上書きして、excludeItemId に ID を入力している場合に該当するタイプのアイテムを返さないようにします。

    RequestResponse
    export class ExtendedSitemapService extends GraphQLSitemapService {
      protected get query(): string {
        return /* GraphQL */ `
          query SitemapQuery(
            $rootItemId: String!
            $language: String!
            $pageSize: Int = 10
            $hasLayout: String = "true"
            $after: String
            $excludeItemId: String = "${this.options.excludeItemId ?? emptyId}"
          ) {
            search(
              where: {
                AND: [
                  { name: "_path", value: $rootItemId, operator: CONTAINS }
                  { name: "_path", value: $excludeItemId, operator: NCONTAINS }
                  { name: "_language", value: $language }
                  { name: "_hasLayout", value: $hasLayout }
                ]
              }
              first: $pageSize
              after: $after
            ) {
              total
              pageInfo {
                endCursor
                hasNext
              }
              results {
                url {
                  path
                }
              }
            }
          }
        `;
      }
      constructor(public options: ExtendedSitemapServiceConfig) {
        super(options);
      }
    注記

    クエリ パラメーターで $excludeItemId: String = "${this.options.excludeItemId ?? emptyId}" を提供します。また、s earch クエリに条件 { name: "_path", value: $excludeItemId, operator: NCONTAINS } も提供します。

カスタム サイトマップ フェッチャーの作成による静的パスのリストのカスタマイズ

新しいサイトマップ サービスが導入されたため、ニーズに合ったサイトマップ フェッチャーを追加できるようになりました。

  • src/lib/sitemap-fetcher.js で、新しいサイトマップ サービスを含む、必要なライブラリをインポートします。

    RequestResponse
    /* eslint-disable @typescript-eslint/no-var-requires */
    import { StaticPath } from '@sitecore-jss/sitecore-jss-nextjs';
    import { GetStaticPathsContext } from 'next';
    import config from 'temp/config';
    import { config as packageConfig } from '../../package.json';
    import { ExtendedSitemapService } from './sitemap-service'; // your new service
    import { ItemIds } from './constants';

リファクタリングされたサイトマップ フェッチャーを使用して、アプリで動的ルートの静的パスのリストをカスタマイズできるようになりました。

一部のアイテム タイプを除く、すべてのページのフェッチ

新しい ExtendedSitemapService を使用して、静的パスのリストから特定のアイテム タイプを除外するサイトマップ フェッチャーを作成できるようになりました。

たとえば、Products 以外のすべてのページをフェッチするには、次のようにします。

  1. src/lib/sitemap-fetcher.jsで、RootSitemapFetcher を実装します。

    RequestResponse
    export class RootSitemapFetcher {
      private _graphqlSitemapService: ExtendedSitemapService;
    
      constructor() {
        this._graphqlSitemapService = new ExtendedSitemapService({
          endpoint: config.graphQLEndpoint,
          apiKey: config.sitecoreApiKey,
          siteName: config.jssAppName,
          excludeItemId: ItemIds.Products, // Exclude products
        });
      }
    
      async fetch(context?: GetStaticPathsContext): Promise<StaticPath[]> {
        return (process.env.EXPORT_MODE
          ? this._graphqlSitemapService.fetchExportSitemap(packageConfig.language)
          : this._graphqlSitemapService.fetchSSGSitemap(context?.locales || [])
        ).then((results) => {
          // Compensate for current bug on Delivery Edge where the root '/products' item
          // is being returned from the search query which excludes it ({ name: "_path", value: $productsItemId, operator: NCONTAINS })
          return results.filter((value) => value.params.path[0] !== 'products');
        });
      }
    }
  2. RootSitemapFetcher のインスタンスをエクスポートします。

    RequestResponse
    export const rootSitemapFetcher = new RootSitemapFetcher();
  3. ファイル src/pages/[[...path]].tsx で、RootSitemapFetcher のインスタンスをインポートします。

    RequestResponse
    import { rootSitemapFetcher } from 'lib/sitemap-fetcher';
  4. getStaticPaths を変更/追加して、rootSitemapFetcher を使用します。

    RequestResponse
    export const getStaticPaths: GetStaticPaths = async (context) => {
      if (process.env.NODE_ENV !== 'development') {
        // Note: Next.js runs export in production mode
        const paths = await rootSitemapFetcher.fetch(context);
    
        return {
          paths,
          fallback: process.env.EXPORT_MODE ? false : 'blocking',
        };
      }
    
      return {
        paths: [],
        fallback: 'blocking',
      };
    };

製品のみのフェッチ

新しい ExtendedSitemapService を使用して、特定のタイプのアイテムのみをフェッチできます。

たとえば、製品のみをフェッチするには:

  1. src/lib/sitemap-fetcher.jsProductSitemapFetcher を実装し、製品パスのみを返すようにします。

    RequestResponse
    export class ProductSitemapFetcher {
      private _graphqlSitemapService: ExtendedSitemapService;
    
      constructor() {
        this._graphqlSitemapService = new ExtendedSitemapService({
          endpoint: config.graphQLEndpoint,
          apiKey: config.sitecoreApiKey,
          siteName: config.jssAppName,
          rootItemId: ItemIds.Products, // Only products
        });
      }
    
      async fetch(context?: GetStaticPathsContext): Promise<StaticPath[]> {
        return (process.env.EXPORT_MODE
          ? this._graphqlSitemapService.fetchExportSitemap(packageConfig.language)
          : this._graphqlSitemapService.fetchSSGSitemap(context?.locales || [])
        ).then((results) => {
          results.forEach((value) => {
            value.params.path.shift(); // Remove the leading 'products' path fragment
          });
          return results;
        });
      }
    }
  2. フェッチャーのインスタンスをエクスポートします。

    RequestResponse
    export const productSitemapFetcher = new ProductSitemapFetcher();
  3. ファイル src/pages/products/[[path]].tsx で、ProductSitemapFetcher のインスタンスをインポートします。

    RequestResponse
    import { productSitemapFetcher } from 'lib/sitemap-fetcher';
  4. getStaticPaths 関数を変更/追加して、productSitemapFetcher を使用します。

    RequestResponse
    export const getStaticPaths: GetStaticPaths = async (context) => {
    
      if (process.env.NODE_ENV !== 'development') {
          // Note: Next.js runs export in production mode
          const paths = await productSitemapFetcher.fetch(context);
    
          return {
            paths,
            fallback: process.env.EXPORT_MODE ? false : 'blocking',
          };
        }
    
        return {
          paths: [],
          fallback: 'blocking',
        };
      };

何かフィードバックはありますか?

この記事を改善するための提案がある場合は、