Home
>
Product
>
Template Top
>
詳細ページ

HubSpot CMS:動画ヒーローバナー(動画ファーストビュー)実装ガイド

Webサイトを訪れた瞬間にユーザーの目を引き、ブランドの世界観を瞬時に伝えるために有効なのが、ファーストビュー(ヒーローエリア)への動画配置です。今回解説する「動画ファーストビューモジュール」を導入すれば、エンジニアの手を借りずに、管理画面から動画のアップロードや挙動の細かな制御が可能になります。

Demo Video

Detail

Webサイトを訪れた瞬間にユーザーの目を引き、ブランドの世界観を瞬時に伝えるために有効なのが、ファーストビュー(ヒーローエリア)への動画配置です。今回解説する「動画ファーストビューモジュール」を導入すれば、エンジニアの手を借りずに、管理画面から動画のアップロードや挙動の細かな制御が可能になります。

1. このモジュールの目的

このモジュールの主な目的は、「誰でも簡単に、高品質なフルスクリーン動画背景やフローティングプレイヤー機能をサイトのトップに構築すること」です。

主なメリットは以下の通りです。

  • 視覚体験の向上: 静止画では伝えきれないブランドの熱量や製品の質感を動的に表現します。
  • 運用負荷の軽減: HubSpotのファイルマネージャーにアップロードした動画を選択するだけで、複雑なHTML/CSSコードを意識せずに背景動画を設定できます。
  • リッチな視聴機能: 通常の背景動画に加え、スクロール時に動画を画面端に小さく表示させ続ける「フローティングプレイヤー」機能をノーコードで有効化できます。

2. 主なユースケース

  • ブランドコンセプトの伝達: サイトの最上部でイメージビデオを自動再生させ、訪問者に一瞬で世界観を共有する。
  • 製品デモンストレーション: プロダクトの使い勝手やシチュエーションを動画で示し、理解を深めてから資料請求などのアクションへ誘導する。
  • ウェビナーや動画コンテンツの常時露出: メイン動画が画面外に消えても、フローティングプレイヤー機能により視聴を継続させ、離脱を防ぐ。

3. 実装と操作ステップ

新規ページの作成から、提供されたコードの適用、現場での運用設定までの全工程を解説します。

ステップ1:ページ作成とモジュールの配置

HubSpot管理画面の「コンテンツ」メニューから新しいページ(ランディングページなど)を立ち上げます。エディター左側のサイドバーで作成したモジュール名を検索し、編集エリアの最上部(ファーストビュー)へドラッグ&ドロップして配置します。

ステップ2:デザインマネージャーでのコード適用

高度な動画制御(オートプレイやフローティング)を有効にするため、デザインマネージャーで以下の作業を行います。

  • ファイルの準備: デザインマネージャーで新規モジュールを作成します。
  • コードの貼り付け: 公開されているソースコードを、それぞれの該当箇所(HTML/HubL、CSS、JS)へそのままコピー&ペーストして保存・公開します。これにより、スクロール検知やカスタム再生ボタンのロジックが組み込まれます。

ステップ3:エディターでの運用・カスタマイズ

コード適用後は、編集画面のサイドパネルからノーコードで詳細を調整できます。

  • 動画の選択: video_fileフィールドからHubSpotにアップロード済みの動画を選択します。
  • 挙動のスイッチ: 「オートプレイ(autoplay)」「ループ(loop_video)」の有効/無効をチェックボックスで切り替えます。
  • ポスター画像の設定: 動画が読み込まれる前に表示される「静止画(poster_image)」を設定し、ユーザーにストレスを与えない表示を実現します。
  • フローティング設定: 動画が隠れた際に画面端へ表示させたい場合は「enable_floating」にチェックを入れます。

モジュールのソースコード

HubSpotのDesign Managerで「新規モジュール」を作成し、以下のコードをそれぞれの箇所に貼り付けてください。

1. fields.json

フィールド定義です。繰り返しフィールド(Items)と、スタイル設定用フィールド(Styles)で構成されています。

[
 {
  "picker": "file",
  "display_width": null,
  "id": "85f1fb81-9630-d95c-8044-f0d56394c9b8",
  "label": "video_file",
  "locked": false,
  "name": "video_file",
  "required": false,
  "type": "file"
 },
 {
  "default": false,
  "display": "checkbox",
  "display_width": null,
  "id": "95362a6b-3ac2-608f-3c46-947fd1f71fd7",
  "label": "autoplay",
  "locked": false,
  "name": "autoplay",
  "required": false,
  "type": "boolean"
 },
 {
  "default": false,
  "display": "checkbox",
  "display_width": null,
  "id": "771f1aed-83f3-dfb2-395d-b5b0f1607d2b",
  "label": "loop_video",
  "locked": false,
  "name": "loop_video",
  "required": false,
  "type": "boolean"
 },
 {
  "default": false,
  "display": "checkbox",
  "display_width": null,
  "id": "2f8d7054-9948-7913-9bad-b16c8976b16d",
  "label": "enable_floating",
  "locked": false,
  "name": "enable_floating",
  "required": false,
  "type": "boolean"
 },
 {
  "default": {
   "size_type": "auto",
   "src": "",
   "alt": null,
   "loading": "lazy"
  },
  "display_width": null,
  "id": "a02f8772-c972-036b-1f2d-ae697f000c31",
  "label": "poster_image",
  "locked": false,
  "name": "poster_image",
  "required": false,
  "resizable": true,
  "responsive": true,
  "show_loading": false,
  "type": "image"
 }
]

Source Code

HTML
<!-- HubSpot カスタム動画モジュール -->
{% set video_src = "" %}
{% if module.video_file %}
  {% if module.video_file.url %}
    {% set video_src = module.video_file.url %}
  {% elif module.video_file.src %}
    {% set video_src = module.video_file.src %}
  {% elif module.video_file is string %}
    {% set video_src = module.video_file %}
  {% endif %}
{% endif %}

{% if video_src %}
<div class="custom-video-player" id="videoPlayerContainer-{{ name }}" 
     data-loop="{{ module.loop_video }}" 
     data-floating="{{ module.enable_floating }}">
  <div class="video-wrapper">
    <video 
      id="customVideo-{{ name }}" 
      class="video-element"
      {% if module.autoplay %}autoplay{% endif %}
      muted
      {% if module.loop_video %}loop{% endif %}
      playsinline
      preload="auto"
      webkit-playsinline="true"
      crossorigin="anonymous"
      {% if module.poster_image.src %}poster="{{ module.poster_image.src }}"{% endif %}
    >
      <source src="{{ video_src }}" type="video/mp4">
    </video>
    
    <div class="play-button-overlay" id="playButtonOverlay-{{ name }}">
      <button class="play-button" id="playButton-{{ name }}" aria-label="動画を再生">
        <svg class="play-icon" viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7z"/></svg>
        <svg class="pause-icon" viewBox="0 0 24 24" fill="currentColor" style="display: none;"><path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"/></svg>
      </button>
    </div>
    
    <div class="progress-bar" id="progressBar-{{ name }}">
      <div class="progress-fill" id="progressFill-{{ name }}"></div>
    </div>
  </div>
  
  {% if module.enable_floating %}
  <div class="floating-player" id="floatingPlayer-{{ name }}" style="display: none;">
    <div class="floating-video-wrapper">
      <video id="floatingVideo-{{ name }}" class="floating-video-element" muted {% if module.loop_video %}loop{% endif %} playsinline crossorigin="anonymous">
        <source src="{{ video_src }}" type="video/mp4">
      </video>
      <div class="floating-play-button-overlay" id="floatingPlayButtonOverlay-{{ name }}">
        <button class="floating-play-button" id="floatingPlayButton-{{ name }}" aria-label="動画を再生">
          <svg class="play-icon" viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7z"/></svg>
          <svg class="pause-icon" viewBox="0 0 24 24" fill="currentColor" style="display: none;"><path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"/></svg>
        </button>
      </div>
      <button class="floating-close-button" id="floatingCloseButton-{{ name }}" aria-label="フローティングプレイヤーを閉じる">
        <svg viewBox="0 0 24 24" fill="currentColor"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>
      </button>
    </div>
  </div>
  {% endif %}
</div>
{% else %}
<div style="padding: 40px; text-align: center; background: #f5f5f5; border-radius: 12px;">
  <p style="color: #666; margin: 0;">動画ファイルを選択してください</p>
</div>
{% endif %}
CSS
.custom-video-player {
  position: relative; max-width: 100%; margin: 0 auto; background: #000; border-radius: 12px; overflow: hidden;
}
.video-wrapper { position: relative; width: 100%; background: #000; min-height: 200px; display: flex; justify-content: center; align-items: center; }
.video-element { max-width: 100%; max-height: 70vh; object-fit: contain; }
.play-button {
  width: 60px; height: 60px; border-radius: 50%; background: rgba(255, 255, 255, 0.9); border: none; cursor: pointer;
}
.progress-bar { position: absolute; bottom: 0; left: 0; width: 100%; height: 4px; background: rgba(255, 255, 255, 0.3); cursor: pointer; }
.progress-fill { height: 100%; width: 0%; background: linear-gradient(90deg, #ff6b6b, #ff8e8e); }

/* フローティングプレイヤー */
.floating-player {
  position: fixed; bottom: 20px; right: 20px; width: 320px; height: 180px; z-index: 1000;
  border-radius: 12px; overflow: hidden; box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4); background: #000;
}
.floating-player.show { animation: fadeIn 0.3s ease forwards; }
@keyframes fadeIn { from { opacity: 0; transform: translateX(100%); } to { opacity: 1; transform: translateX(0); } }
Javascript
(function() {
  'use strict';
  function CustomVideoPlayer(containerId) {
    var self = this;
    this.suffix = containerId.replace('videoPlayerContainer-', '');
    this.container = document.getElementById(containerId);
    this.video = document.getElementById('customVideo-' + this.suffix);
    this.floatingPlayer = document.getElementById('floatingPlayer-' + this.suffix);
    this.floatingVideo = document.getElementById('floatingVideo-' + this.suffix);
    this.enableFloating = this.container.getAttribute('data-floating') === 'true';

    this.init = function() {
      if (!self.video) return;
      this.setupEventListeners();
      if (this.enableFloating) this.setupScrollDetection();
    };

    this.setupEventListeners = function() {
      this.video.addEventListener('click', function() { self.togglePlay(); });
      if (document.getElementById('playButton-' + this.suffix)) {
        document.getElementById('playButton-' + this.suffix).addEventListener('click', function(e) {
          e.stopPropagation(); self.togglePlay();
        });
      }
      this.video.addEventListener('timeupdate', function() { self.updateProgress(); });
    };

    this.setupScrollDetection = function() {
      if (typeof IntersectionObserver !== 'undefined') {
        var observer = new IntersectionObserver(function(entries) {
          entries.forEach(function(entry) {
            if (!entry.isIntersecting && !self.video.paused) {
              self.showFloatingPlayer();
            } else if (entry.isIntersecting && self.isFloating) {
              self.hideFloatingPlayer();
            }
          });
        }, { threshold: 0.1 });
        observer.observe(self.container);
      }
    };

    this.togglePlay = function() {
      if (this.video.paused) this.video.play();
      else this.video.pause();
    };

    this.showFloatingPlayer = function() {
      this.isFloating = true;
      this.video.pause();
      this.floatingPlayer.style.display = 'block';
      this.floatingPlayer.classList.add('show');
      this.floatingVideo.currentTime = this.video.currentTime;
      this.floatingVideo.play();
    };

    this.init();
  }

  function initializeAllPlayers() {
    document.querySelectorAll('[id^="videoPlayerContainer-"]').forEach(function(container) {
      if (!container.hasAttribute('data-initialized')) {
        new CustomVideoPlayer(container.id);
        container.setAttribute('data-initialized', 'true');
      }
    });
  }
  window.addEventListener('load', initializeAllPlayers);
})();

FAQ

スマートフォンでも自動再生されますか?

はい。コード内に muted および playsinline 属性が含まれているため、最新のスマートフォンブラウザでも自動再生が可能です。

動画のサイズ(高さ)を調整することはできますか?

可能です。モジュールの設定パネル、またはCSSの max-height などの数値を調整することで、画面全体(100vh)にするか、特定の高さに抑えるかを変更できます。

YouTube動画をこのモジュールで表示できますか?

本モジュールはHubSpotに直接アップロードされたMP4ファイル等の直接参照に最適化されています。YouTube動画を使用する場合は、HubSpot標準の動画モジュール、または外部埋め込み用コードの活用をお勧めします。