4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Salesforce B2C Commerce の SFRA での CSS や JS の適用について

Last updated at Posted at 2022-10-27

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

今回の記事では、SFRAに対してデザインの修正を行いたい場合やクライアントサイドに新しく機能を追加したい場合の方法を紹介したいと思います。

前提としてSFRAについて知っておいた方がいいこと

① app_storefront_base のコードは修正しないようにしましょう

SFRAでは app_storefront_base というカートリッジを使用していますが、そのカートリッジ内のソースコードを修正してしまうと、後の SFRA アップデートに影響が出たり、その他想定外の影響が出ることがありますので、修正しないようにしましょう。

② Bootstrap 4 を利用しています

SFRA では NPM レジストリ上の bootstrap 4 をインポートして利用しています。そのためグリッドシステムやその他の多くのコンポーネントを利用できます。

③ jQuery を利用しています

SFRA では NPM レジストリ上の jQuery をインポートして利用しています。クライアントサイドでの機能追加は基本的にはjQueryを利用して行います。

④ static フォルダに静的ファイルは設置します

SFRA では CSS / JS / Image / Font などの静的ファイルは static フォルダに設置して利用します。(もちろん商品画像やバナー画像などは別です)

⑤ SCSS を利用します

SFRA では SCSS ファイルをコンパイルし、static フォルダ内に CSS ファイルを生成してスタイルを適用します。
JS, SCSS のコンパイルについては Webpack を利用していますが、sgmf-scripts というコマンドを通して利用できますので、前回紹介した記事をご覧ください。

JS の作成

JS は cartridge/client/default/js フォルダ内に作成しますが、
基本的には下記のようなフォルダ構成になります。(箇条書きで書いているので若干分かりにくくてすみません。。)

・ /cartridge/client/default/js
    ・ モジュール1
        ・ モジュール1.js
    ・ モジュール2
        ・ モジュール2.js
    ・ モジュールをインポートしてISMLでインポートされる.js

シンプルな例を作成してみます。下記のようなフォルダ構成になっているとします。

・ /cartridge/client/default/js
    ・ module
        ・ module.js
    ・ sample.js

下記のようにモジュールを作成します。 bindSomething のように関数を設定するとページが読み込まれた後に実行されるのでここで HTML にイベントをバインドすることが多いです。また、methods のようにオブジェクトを設定しているとページ読み込み後に呼び出されませんので、クライアントでの操作時に実行したい関数などを定義できます。

/cartridge/client/default/js/module/module.js
module.exports = {
    bindSomething: function () {
        $('.sample').on('click', function () {
            // Do shomething.
        });
    },
    methods: {
        sampleMethod: function(){
            // Do shomething.
        },
    }
}

作成したモジュールは下記のようにインポートしてきます。

/cartridge/client/default/js/sample.js
'use strict';

var processInclude = require('base/util');

$(document).ready(function () {
    processInclude(require('./module/module'));
});

作成した JS ファイルがコンパイルされて生成された sample.js を ISML ファイルで下記のように呼び出して利用します。

<isdecorate template="common/layout/page">
    <isscript>
        var assets = require('*/cartridge/scripts/assets.js');
        assets.addJs('/js/sample.js');
    </isscript>
    ==OMIT==
</isdecorate>

SCSS の作成

SCSS も JS に似ていて、 cartridge/client/default/scss フォルダ内に作成しますが、
基本的には下記のようなフォルダ構成になります。(たまにモジュールのフォルダから直接 ISML でインポートすることもあります。)

・ /cartridge/client/default/scss
    ・ モジュール1
        ・ _モジュール1.scss
    ・ モジュール2
        ・ モジュール2.scss
    ・ モジュールをインポートしてISMLでインポートされる.scss

シンプルな例を作成してみます。下記のようなフォルダ構成になっているとします。

・ /cartridge/client/default/scss
    ・ module
        ・ _module.scss
    ・ sample.scss

下記のようにモジュールを作成します。Bootstrap などのライブラリモジュールの呼び出しも可能です。

/cartridge/client/default/scss/module/_module.scss
@import "bootstrap/scss/variables";
@import "bootstrap/scss/mixins/breakpoints";

.someClass {
   // Some style.
}

作成したモジュールは下記のようにインポートしてきます。

/cartridge/client/default/scss/sample.scss
@import "module/module";

作成した SCSS ファイルがコンパイルされて生成された sample.css を ISML ファイルで下記のように呼び出して利用します。

<isdecorate template="common/layout/page">
    <isscript>
        var assets = require('*/cartridge/scripts/assets.js');
        assets.addCss('/css/sample.css');
    </isscript>
    ==OMIT==
</isdecorate>

Tips
ISML からインポートされないようなパーシャル SCSS ファイルはお作法として _ (アンダーバー) をプリフィックスとしてつけた方が良さそうです。(参考

SFRA の CSS の上書き

例えば、app_custom_sample というカートリッジを作成してホームページの CSS を上書きたいとします。
SFRA のデフォルトのホームページは下記の SCSS を利用しています。
app_storefront_base/cartridge/client/default/scss/homePage.scss

CSS を上書きする場合はカスタムカートリッジの同じ階層に同じファイル名のファイルを作成します。
app_custom_sample/cartridge/client/default/scss/homePage.scss

そして下記のように、@import "base/homePage"; で SFRA の SCSS をインポートしてから上書きを行います。

app_custom_sample/cartridge/client/default/scss/homePage.scss
@import "base/homePage";

.page-title {
    color:red !important;
}

Bootstrap の利用

基本的にはサイト上に記載のあるのコンポーネントは使用できます。
例えばサンプルにあるアラートの HTML を下記のように ISML に記載します。

<div class="alert alert-primary" role="alert">
       A simple primary alert—check it out!
</div>

すると、下記のようにスタイルが適用された状態で表示されます。
image (45).png

Tips

一部コメントアウトされて利用できないものもありました。( コード (Account Manager アカウント必要))
この場合は、main.js を修正する必要があります。例えば、app_custom_sample/cartridge/client/default/js/main.js を作成して下記のように記載します。

app_custom_sample/cartridge/client/default/js/main.js
require('base/main');
require('bootstrap/js/src/tooltip.js');

すると下記のように Bootstap の API を呼び出せます。

$('[data-toggle="tooltip"]').tooltip();

SFRA の JS の上書き

例えば商品詳細ページの JS を上書きしたいとします。

まず、SFRA の商品詳細ページでは、app_storefront_base/cartridge/client/default/js/productDetail.js
を読み込んでおり、さらにこの JS はモジュールとして、app_storefront_base/cartridge/client/default/js/product/detail.js を読み込んでいます。

上書きする場合は、下記のようにファイルを作成します。

まず、productDetail.js をコピーしてきます。今回はそのまま使いますが、SFRA のモジュールをそのまま使う場合は、
processInclude(require('base/hoge'));のようにルートのエイリアスに base を使うように変更しましょう。

app_storefront_base/cartridge/client/default/js/productDetail.js
'use strict';

var processInclude = require('base/util');

$(document).ready(function () {
    processInclude(require('./product/detail'));
});

今回は、detail.js の関数 showSpinner を上書きしたいと思います。完全に上書きしたい場合は、base.showSpinner() の部分は消しても良いかと思います。

app_storefront_base/cartridge/client/default/js/product/detail.js
'use strict';
var base = require('base/product/detail');

module.exports = {
    ...base,
    showSpinner: function () {
        base.showSpinner()
        // Add logic.
    },
};

サイト全体の CSS、JS 修正

SFRA でサイト全体に適用されている CSS, JS は、global.scss, skin.scss, main.js です。
あくまで私の所感 ですが、この中で、global.scssmain.js はあくまでモジュールのインポートに徹した方がいいような気がします。
例えば、下記のような使い方です。

global.scss では下記のように自作の変数やモジュール、ライブラリのモジュールをインポートするために使う。

global.scss
@import "base/global";
@import "variables";
@import "custom/custom";

skin.scss では、カスタムプロパティの上書きやちょっした CSS の追加として使う。

skin.scss
@import "base/skin/skin";

:root {
    --skin-banner-background-color-1: #3f0a00;
    --skin-banner-background-color-2: #000009;
}

.hoge {
    // Some code
}

main.js は自作のモジュールやライブラリのモジュールをインポートするために使う。

main.js
require('base/main');

$(document).ready(function () {
    processInclude(require('./custom/custom'));
});

require('bootstrap/js/src/tooltip.js');

スクリプトを追加したい

Google Analytics などの CDN で提供されているようなライブラリをインポートしたい場合やちょっとしたスクリプトを埋め込みたい時があるかと思います。
そういった場合に便利なのが SFRA であらかじめ用意されている Hooks を利用することです。
Hooks の利用方法については以前のQiitaをご参照ください。

追加場所としては下記の2つがあり、それぞれに Hook 名があります。

  • head タグ内
    • app.template.afterFooter
  • footer タグの後
    • app.template.htmlHead

まず下記のように、htmlHead , afterFooter と言う名前の関数名でエクスポートしたJSを作成します。
下記の例では、footer タグの後には、Business Manager の マーチャントツール > サイト環境設定 > カスタムサイト環境設定グループ で設定した値(SampleSnippet)をレンダリングしており、head タグ内には、hooks/afterFooter テンプレートの中身をレンダリングしています。

cartridge/scripts/hooks/sampleTemplate.js
const Site = require('dw/system/Site');
const velocity = require('dw/template/Velocity');
var ISML = require('dw/template/ISML');

const afterFooter = function () {
    const currentSite = Site.current;
    const snippet = currentSite.getCustomPreferenceValue('SampleSnippet');
    if (snippet) {
        velocity.render(snippet, null);
    }
};

function htmlHead(params) {
    var templateName = 'hooks/afterFooter';
    try {
        ISML.renderTemplate(templateName, params);
        // Another option is to render using Velocity templates
        /*
         params.message = params.message || 'world';
         velocity.render('Hello $message', params);
         */
    } catch (e) {
        Logger.error('Error while rendering template ' + templateName);
    }
}

exports.htmlHead = htmlHead;
exports.afterFooter = afterFooter;

呼び出す際は下記のように hooks.json の設定をお忘れなく。

cartridges/app_storefront_base/hooks.json
{
  "hooks": [
    {
      "name": "app.template.afterFooter",
      "script": "~/cartridge/scripts/hooks/sampleTemplate"
    },
    {
      "name": "app.template.htmlHead",
      "script": "~/cartridge/scripts/hooks/sampleTemplate"
    }
  ]
}
4
2
0

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
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?