Salesforce B2C/B2B Commerce でデザインを変更してみる（後編）


※ これから記載する事項は、私が所属する会社とは切関係のない事柄です。

今回は前回の「[Salesforce B2C/B2B Commerce でデザインを変更してみる（前編）](
https://qiita.com/syunyama/items/0062adb4cbf6ff143cf9)」に続く後編です。
静的ファイルの読み込み方法とフォントの追加設定をやってみたいと思います。


## 静的ファイルの読み込み

### リソースの種類

静的リソースには下記の２種類存在します。

#### 静的リソース

**Setup > Custom Code > Static Resources** からファイルをアップロードして利用するリソースです。


#### 外部リソース

`https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js` のような外部のサーバーにホスティングされているリソースです。外部のリソースを利用する場合はContent Security Policy (CSP)の設定が必要になります。


### リソースの読み込み方法

リソースを読み込む方法には下記の３つがあります。

#### LWC の JS ファイルからの読み込み

` loadScript` や `loadStyle` のAPIを利用してJSファイル内からリソースを読み込みます。


#### Experience Builder からの読み込み（全ページ）

Experience Builder の設定から **Advanced > Edit Head Markup** から head タグに挿入することで読み込みます。
![スクリーンショット 2023-01-29 21.01.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2110894/bdbcde98-87d0-7f3c-1650-93e2942fded9.png)




#### Experience Builder からの読み込み（特定ページ）

Experience Builder の設定から特定のページの設定内の **Edit Head Tag** から head タグに挿入することで読み込みます。
※ 全ページでの読み込みと違い script の読み込みはできません。
![スクリーンショット 2023-01-29 21.07.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2110894/263ff5d4-5fcb-8a06-bd43-a47f89c33094.png)


## 静的ファイルの読み込みをやってみる


今回は下記のツールを別々の方法で利用してみたいと思います。

[Materialize](https://materializecss.com/) の利用

* Experience Builder からの読み込み（特定ページ）で外部リソースCSSの読み込み
* LWC の JS ファイルからの読み込みで外部リソースJSの読み込み


[TuiCss](https://github.com/vinibiavatti1/TuiCss) の利用

* Experience Builder からの読み込み（全ページ）で静的リソースCSSの読み込み


[Google のマテリアルアイコン](https://developers.google.com/fonts/docs/material_icons?hl=ja)の利用

* LWC の JS ファイルからの読み込みで外部リソースCSSの読み込み


[D3.js](https://d3js.org/) の利用

* LWC の JS ファイルからの読み込みで静的リソースJSの読み込み


[Lodash](https://lodash.com/) の利用

* Experience Builder からの読み込み（全ページ）で静的リソースJSの読み込み



### 静的リソースの確認

静的リソースは２パターンの設定をしています。

* D3
    * d3.js を利用するための JS ファイルを単体でアップロードしたリソース
* sample
    * TuiCss を利用するために、下記のような構造を持つsampleフォルダをzipファイル化したものをアップロードしたリソース。（後ほど利用するフォントも同時に入れてあります）
    ![スクリーンショット 2023-01-29 21.36.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2110894/d411890e-236d-553b-6c85-363af2f1569c.png)

![スクリーンショット 2023-01-29 21.34.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2110894/5eeafe1e-b01c-ff2d-59fc-124dd0e494ac.png)



### Experience Builder からの読み込み（全ページ）の確認

tuicss の CSS と lodash の JS を読み込んでいます。
![スクリーンショット 2023-01-29 21.46.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2110894/31867a50-b722-9176-78c5-0e079c70dd06.png)





### Experience Builder からの読み込み（特定ページ）の確認

materialize の CSS を読んでいます。
![スクリーンショット 2023-01-29 21.47.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2110894/9632692a-bf7a-5b23-72b3-7babbff5938e.png)





### 確認のための LWC

```html:sampleStatic.html
<template>
  <div class="container">
    <div class="row">
      <div class="col m2">
        <div class="white-255" style="text-align: center">Materialize</div>
      </div>
      <div class="col m10">
        <div class="card">
          <div class="card-content">
            <form action="#">
              <label>Sample Date</label>
              <input type="text" class="datepicker" />
            </form>
          </div>
        </div>
      </div>
    </div>
    <div class="row">
      <div class="col m2">
        <div class="white-255" style="text-align: center">Material Icon</div>
      </div>
      <div class="col m10">
        <a class="btn-floating pulse"><i class="material-icons">menu</i></a>
      </div>
    </div>
    <div class="row">
      <div class="col m2">
        <div class="white-255" style="text-align: center">D3</div>
      </div>
      <div class="col m10"><div class="d3"></div></div>
    </div>
    <div class="row">
      <div class="col m2">
        <div class="white-255" style="text-align: center">TuiCSS Button</div>
      </div>
      <div style="margin-bottom: 1rem" class="col m10">
        <button class="tui-button">Button</button>
      </div>
    </div>
  </div>
</template>
```


ここで LWC の JS ファイルからの読み込みを確認できます。

```js:sampleStatic.js
/* eslint-disable no-undef */
import { LightningElement } from 'lwc';
import { loadScript, loadStyle } from 'lightning/platformResourceLoader';
import D3_RESOURCE from '@salesforce/resourceUrl/D3';

export default class SampleStatic extends LightningElement {
    async connectedCallback() {
        // Icon for Materialize
        await loadStyle(this, "https://fonts.googleapis.com/icon?family=Material+Icons");
        
        // Materialize
        await loadScript(this, "https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js");
        let elems = this.template.querySelectorAll('.datepicker');
        M.Datepicker.init(elems);

        // D3
        await loadScript(this, D3_RESOURCE);
        let dataset = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
        let doms = this.template.querySelector(".d3")
        let container = d3.select(doms)
        let svg = container.append("svg");
        svg.attr("width", 500)
            .attr("height", 100);
        let circles = svg.selectAll("circle")
            .data(dataset)
            .enter()
            .append("circle");
        circles.attr("cx", function (d, i) { return i * 50 + 20; })
            .attr("cy", 50)
            .attr("r", function (d) { return d * 2; })

        // Lodash
        console.log("Lodash Test. This should be true.")
        console.log(_.isString("abc"))
    }
}
```

```xml:sampleStatic.js-meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <masterLabel>Sample Static</masterLabel>
    <description>Sample Static</description>
    <apiVersion>56.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightningCommunity__Page</target>
    </targets>
</LightningComponentBundle>
```




### Content Security Policy (CSP) の設定

設定方法については[ヘルプ](https://help.salesforce.com/s/articleView?id=sf.comm_cms_channel.htm&type=5)を参照してください。

もし外部リソースを利用していてCSPの設定ができていない時はこのような画面が表示されます。
![スクリーンショット 2023-01-27 20.44.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2110894/6d9038df-e3e1-acff-aa8e-02bc4befebae.png)



設定を `Relaxed: CSP` に変更し、 `Allow URL` をクリックします。
![スクリーンショット 2023-01-27 20.44.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2110894/ff93dd07-94cc-d0b9-dcaa-cf928afaccc4.png)


URLを確認して `Allow` ボタンで許可します。
![スクリーンショット 2023-01-29 20.38.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2110894/718389aa-2088-ccec-ad08-f63fc6717fbd.png)



### 動作確認

作成した Sample Static という LWC を任意の場所に配置すると下記の画像のようにCSSが当たっていることが確認できます。
![スクリーンショット 2023-01-29 22.13.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2110894/f555f455-9fb1-41ed-84ec-98454860f614.png)

また、Materializeの [Date Picker](https://materializecss.com/pickers.html) も正しく動いていることが確認でき、正常にJSが読み込めていることも確認できます。
![スクリーンショット 2023-01-29 22.13.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2110894/cddc8ece-6b7c-6a92-f4d7-f1ea2340a475.png)


さらに、JS 内で利用している Loadash が正しく動いていることもブラウザの開発ツールのコンソールから確認できました。
![スクリーンショット 2023-01-29 22.13.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2110894/a201e786-18e6-6c61-2bcb-3c947bc25248.png)





## フォントの追加

フォントを追加する際のヘルプは[こちら](https://developer.salesforce.com/docs/atlas.en-us.exp_cloud_lwr.meta/exp_cloud_lwr/brand_custom_fonts.htm)です。また今回設定するカスタムフォントはテーマにも反映させることが可能なので、その際は[こちら](https://developer.salesforce.com/docs/atlas.ja-jp.communities_dev.meta/communities_dev/communities_dev_customize_font.htm)をご覧ください。

今回は静的リソースを利用して[Branda Font](https://www.fontspace.com/branda-font-f30036) というフォントを適用してみたいと思います。
先述のsampleフォルダに入っている `Branda-yolq.ttf` というフォントファイルを利用していきたいと思います。
Experience Builder からの読み込み（全ページ）をする際のエディタに下記の内容を追記し、`myFirstFont` という新しいフォントを利用してみます。

```css
<style>
   @font-face {
      font-family: 'myFirstFont';
      src: url('{ basePath }/sfsites/c/resource/sample/sample/Branda-yolq.ttf') format('truetype');
   }
</style>
```

![スクリーンショット 2023-01-29 22.35.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2110894/8b9912ad-74cc-7ced-a619-e5d6f3796601.png)




### 確認

LWCのHTMLに下記のように記述し、コンポーネントを設定します。

```html
<p style="font-family: 'myFirstFont'; font-size: 3rem">Font Test</p>
```

すると、ちゃんとフォントが適用されていることが確認できます。

![スクリーンショット 2023-01-29 22.41.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2110894/23a6e502-dcb1-4a6e-dc11-02c42ee1c111.png)