Sitecore JSSでページ間で共通のヘッダーを作成する
Tags: sitecore, jss, react
Published: 2020-01-11 05:30:21

一般的なSitecoreの開発では、ヘッダーのような全ページで共通のデータソースを使うレンダリングを必ずと言っていいほど作成します。  
JSSでも共有コンポーネントを使用することで、同様の機能を実現できます。  

## Headerコンポーネントを作成する
まずはHeaderコンポーネントを作成しましょう。コンポーネントの作成には以下のコマンドを使用します。

```bash
> jss scaffold Header
```

作成された`/sitecore/definitions/components/Header.sitecore.js`で、Headerコンポーネントのデータソーステンプレートにフィールドを追加します。

```js
// eslint-disable-next-line no-unused-vars
import { CommonFieldTypes, SitecoreIcon, Manifest } from '@sitecore-jss/sitecore-jss-manifest';

/**
 * Adds the Header component to the disconnected manifest.
 * This function is invoked by convention (*.sitecore.js) when 'jss manifest' is run.
 * @param {Manifest} manifest Manifest instance to add components to
 */
export default function(manifest) {
  manifest.addComponent({
    name: 'Header',
    icon: SitecoreIcon.DocumentTag,
    fields: [
      // headingフィールドを削除し、headerContentフィールドを追加
      { name: 'headerContent', type: CommonFieldTypes.RichText }
    ],
    /*
    If the component implementation uses <Placeholder> or withPlaceholder to expose a placeholder,
    register it here, or components added to that placeholder will not be returned by Sitecore:
    placeholders: ['exposed-placeholder-name']
    */
  });
}
```

次に`/src/components/Header/index.js`を編集し、先程定義したフィールドを表示するよう修正します。

```react
import React from 'react';
import { RichText } from '@sitecore-jss/sitecore-jss-react';

const Header = (props) => (
  <div>
    {/* 定義したフィールドを表示 */}
    <RichText field={props.fields.headerContent} />
  </div>
);

export default Header;
```

## 共有コンポーネントを定義する
ページ間で共有するコンポーネントは、`/data/component-content`フォルダに定義します。  
このフォルダは以下のようなパス構成にする必要があります。  

- `data/`
    - `component-content/`
        - `<コンポーネント名>/`
            - `<アイテム名>/`
                - `<言語名>.yml`

今回はヘッダーを作成するので、`/data/component-content/Header/shared-header/en.yml`（アイテム名がshared-headerのHeaderコンポーネント）に定義します。  
`en.yml`ファイルの中身は以下のとおりです。  

```yaml
# このコンポーネントを参照するためのプロジェクトで一意なIDを指定
id: header-banner
# コンポーネントのアイテム名
name: shared-header
# コンポーネントのアイテムの表示名
displayName: Shared Header
# コンポーネントの種類
componentName: Header
# コンポーネントのフィールド一覧
fields:
  headerContent: |
    <header>
      <p> Sample Webiste</p>
    </header>
```

この時点で`jss deploy items -c`コマンドを実行しSitecoreへデプロイすると、`<jssroot>/Components/Header/shared-header`にアイテムが作成されます。  

## 共有コンポーネントをページに挿入する。
ページの定義（/data/routes）に先程定義した共有コンポーネントを挿入します。挿入時には先程作成した共有コンポーネントのIDを指定します。  

例として、デフォルトで用意されている`/data/routes/en.yml`に挿入してみます。

```diff
 id: home-page

 # Route-level fields are appropriate for page level data like <title> contents
 # Define route level fields in /sitecore/definitions/routes.sitecore
 fields:
   pageTitle: Welcome to Sitecore JSS
 # Define the page layout starting at the root placeholder - in this case, 'jss-main'
 # root placeholder names are defined in the package.json config section (required for Sitecore deployment)
 placeholders:
   jss-main:
+    - id: shared-header # IDで共有コンポーネントを指定
     - componentName: ContentBlock
       fields:
         heading: Welcome to Sitecore JSS

  jss-main:
 ###### (省略) #######
```

`jss deploy items -c`を実行して共有コンポーネントを指定したページのプレゼンテーション詳細を確認してみてください。  
最終レイアウトにHeaderコンポーネントが入っており、そのデータソースが`<jssroot>/Components/Header/shared-header`になっているはずです。（共有でない場合は各ページアイテム下の`Page Components`フォルダ内になります）