Contents
HubSpot CMS の基本構成と Design Manager の概要
HubSpot CMS は 「テンプレート」・「モジュール」・「HubL」 の3要素でページを組み立てます。このセクションではそれぞれの役割と、ローカル環境でデザイン作業を開始する手順をご紹介します。
テンプレート・モジュール・HubL の役割
| 要素 | 主な機能 |
|---|---|
| テンプレート | ページ全体のレイアウト(ヘッダー、フッター、コンテンツ領域)を定義。複数ページで共通化できる。 |
| モジュール | 画像・テキスト・ボタンなど再利用可能な部品。Design Manager の UI 上でドラッグ&ドロップできる。 |
| HubL | HubSpot 独自のサーバー側テンプレート言語。条件分岐やデータ取得、Asset 管理タグを提供する。 |
ポイント:HubL は
{% if %}や{% hubdb_table_rows "table_name" %}といったタグで動的コンテンツを簡潔に記述できます。
ローカル開発環境の構築手順
- Node.js のインストール
-
推奨バージョンは v18 以上(HubSpot CLI が公式にサポートしています)。
-
HubSpot CLI の導入
bash
npm install -g @hubspot/cli
- CLI で HubSpot アカウントへ認証
bash
hs auth login --scope content
- プロジェクトの初期化
bash
hs init my-project
cd my-project
- Git リポジトリを作成し、リモートにプッシュ(チーム開発が前提の場合)
bash
git init
git add .
git commit -m "Initial commit"
git remote add origin <your-repo-url>
git push -u origin main
これだけでローカルエディタからテンプレートやモジュールを編集し、hs upload -p で即座に HubSpot に反映できます。
カスタムテンプレート作成手順
カスタムテンプレートは HTML と HubL を組み合わせて構築します。この章ではフォルダ構造の決め方と、実装例を交えて段階的に説明します。
フォルダ構造のベストプラクティス
|
1 2 3 4 5 6 7 8 9 10 11 |
my-project/ ├─ src/ │ ├─ templates/ # テンプレート本体 │ │ └─ blog-post.html │ ├─ modules/ # カスタムモジュール │ ├─ partials/ # ヘッダー・フッター等の部品 │ └─ assets/ │ ├─ scss/ │ └─ js/ └─ hubspot.config.yml |
Why:HubSpot は
src/templates配下をテンプレートとして自動ビルドするため、規則的な配置がそのままプレビューに反映されます。
HTML と HubL を組み合わせた基本テンプレート
以下はブログ記事ページの最小構成です。コメントで主要ポイントを示しています。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
{% raw %} <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>{{ page_meta.title }}</title> <!-- SEO 用 meta --> <meta name="description" content="{{ page_meta.description }}"> {{ require_css("custom.css") }} {# CSS アセットの自動ロード #} </head> <body> {% include "partials/header.html" %} <main class="hub-custom__content"> <h1>{{ content.name }}</h1> <!-- HubL で本文を安全に出力 --> <div class="rich-text">{{ content.post_body|safe }}</div> </main> {% include "partials/footer.html" %} {{ require_js("custom.js") }} {# JS アセットの自動ロード #} </body> </html> {% endraw %} |
{{ page_meta.title }}と{{ page_meta.description }}は HubSpot が自動的に生成する SEO データです。require_css/require_jsは Asset 管理 用タグで、ビルド時に最適化されたファイルが配信されます。
再利用可能なカスタムモジュールの作り方
モジュールは module.json(設定)と module.html(表示ロジック)の2ファイルだけで完結します。ここでは「カード」モジュールを例に、実装手順と UI カスタマイズ方法を示します。
module.json の構成要素
| キー | 説明 |
|---|---|
label |
Design Manager 上に表示される名前 |
is_available_for_new_content |
新規コンテンツ作成時に選択可能か |
fields |
エディタで入力できるフィールド定義(type, label, name など) |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
{ "label": "カード", "is_available_for_new_content": true, "fields": [ { "name": "title", "label": "タイトル", "type": "text" }, { "name": "image", "label": "画像", "type": "file", "allowed_file_types": ["png", "jpg", "jpeg"] }, { "name": "link_url", "label": "リンク URL", "type": "url" } ] } |
module.html の実装例
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
{% raw %} <div class="hub-custom__card"> {% if module.image %} <img src="{{ module.image.src }}" alt="{{ module.title | escape }}"> {% endif %} <h3>{{ module.title }}</h3> {% if module.link_url %} <a href="{{ module.link_url }}" class="btn">詳しく見る</a> {% endif %} </div> {% endraw %} |
module.image.srcはアップロードされた画像の URL。| escapeフィルタで XSS を防止しつつ、アクセシビリティ向上のために alt 属性を必ず設定します。
Design Manager の「モジュール」タブからプレビューできるので、実装後すぐに見た目と動作を確認できます。
カスタム CSS/JavaScript を安全に組み込むベストプラクティス
HubSpot では Content Security Policy (CSP) が標準で適用されており、インラインスクリプトはブロックされます。そのため、外部ファイルとして読み込む形が必須です。以下の手順で名前空間化とロードタイミングを最適化しましょう。
1. SASS → CSS のビルドフロー
|
1 2 3 4 |
# プロジェクト直下で実行(package.json にスクリプト追加推奨) npm install -D sass npx sass src/assets/scss/main.scss src/assets/css/custom.css --no-source-map |
main.scss の例(名前空間を付与)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
/* すべてのカスタムスタイルは .hub-custom プレフィックスで囲む */ .hub-custom { .hero { background: #004080; color:#fff; } .button { @extend %primary-button; &:hover { opacity:0.9; } } /* コントラスト確保のためのユーティリティクラス */ .high-contrast { color: #000; background-color: #fff; } } |
2. テンプレートでのアセット呼び出し
|
1 2 3 |
{{ require_css("custom.css") }} <script src="{{ get_asset_url('custom.js') }}" defer></script> |
defer属性により、HTML の解析が完了した後にスクリプトが実行され、ページ描画を阻害しません。{{ get_asset_url() }}は CDN に最適化された URL を返すため、キャッシュ効率が向上します。
3. CSP に配慮した実装例
|
1 2 3 |
<!-- インラインスクリプトは使用しない --> <script src="{{ get_asset_url('analytics.js') }}" defer></script> |
注意:
hs_scriptタグ(例:<script type="text/hs-script" data-hsjs='...'></script>)は HubSpot が提供する特別なスクリプトローダーで、CSP に自動的に適合します。インラインコードが必要な場合はこのタグを利用してください。
サーバーレス Functions と HubDB の連携
HubSpot の Functions(サーバーレス)と HubDB を組み合わせることで、外部 API から取得したデータや内部テーブルの内容をテンプレートに動的に埋め込むことができます。ここでは正しい呼び出しシンタックスと実装例を示します。
HubSpot Functions の作成とデプロイ
ファイル構成(src/functions ディレクトリ)
|
1 2 3 4 |
src/ └─ functions/ └─ getWeather.js |
getWeather.js(Node.js)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
// src/functions/getWeather.js exports.main = async (context, sendResponse) => { const apiKey = process.env.OPENWEATHER_API_KEY; const city = "Tokyo"; const url = `https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${apiKey}`; try { const res = await fetch(url); if (!res.ok) throw new Error(`API error ${res.status}`); const data = await res.json(); // 気温(K)を摂氏に変換して返す const celsius = (data.main.temp - 273.15).toFixed(1); sendResponse({ statusCode: 200, body: JSON.stringify({ tempC: celsius }) }); } catch (e) { sendResponse({ statusCode: 500, body: JSON.stringify({ error: e.message }) }); } }; |
デプロイ手順
|
1 2 3 |
hs functions deploy # デプロイ後に表示される URL(例: https://api.hubspot.com/functions/v1/<portal-id>/getWeather) |
テンプレート側から Functions を呼び出す正しいシンタックス
HubSpot の公式ドキュメントでは hubspot.function タグを以下のように使用します。
|
1 2 3 4 5 6 7 |
{% raw %} {% set weather = hubspot.function("getWeather") %} <div class="weather"> <p>現在の東京の気温は {{ weather.tempC }}℃です。</p> </div> {% endraw %} |
hubspot.functionは 同期的 に結果を取得できる(関数が短時間で完了する前提)。- 長時間実行が予想される場合は、非同期 API エンドポイント経由でフロントエンドから fetch する方法も検討してください。
HubDB テーブルのデータ表示例
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
{% raw %} <ul class="team-list"> {% hubdb_table_rows "team_members", limit=8, order_by="name" as rows %} {% for row in rows %} <li class="member"> <img src="{{ row.photo_url }}" alt="{{ row.name | escape }}"> <h4>{{ row.name }}</h4> <p>{{ row.role }}</p> </li> {% endfor %} </ul> {% endraw %} |
hubdb_table_rowsタグは HubDB の行を取得し、as rowsで変数に格納します。limitとorder_byを活用すれば、表示件数や並び順の調整が簡単です。
プレビュー・テストフローと SEO/アクセシビリティチェック
変更は必ず ローカルプレビュー → ステージング環境 の順で検証し、最終的に本番へデプロイします。また、検索エンジン評価やユーザー体験を損なわないよう、以下のチェックリストと実装例を活用してください。
プレビュー機能の使い方(CLI)
|
1 2 3 |
# ポータル ID を指定してローカルサーバー起動 hs preview -p 123456 |
- コマンド実行後、デフォルトブラウザが自動で
https://app.hubspot.com/preview/<portal-id>に接続し、リアルタイムで変更を確認できます。 - Design Manager の「Preview」タブでは デバイス切替 と アクセシビリティツール(axe-core が組み込まれています)も利用可能です。
SEO・アクセシビリティ実装例
| チェック項目 | 実装サンプル |
|---|---|
| meta タグ | html<br>{{ require_css("custom.css") }}<br><title>{{ page_meta.title }}</title><br><meta name="description" content="{{ page_meta.description }}"> |
| 構造化データ (JSON‑LD) | html<br>{% raw %}<script type="application/ld+json">{% endraw %}<br>{ " @context": "https://schema.org", " @type": "Article", "headline": "{{ content.name }}", "author": { "@type": "Person", "name": "{{ content.author }}" }, "datePublished": "{{ content.publish_date|datetimeformat("%Y-%m-%d") }}" }<br>{% raw %}</script>{% endraw %} |
| ARIA 属性 | html<br><button class="hub-custom__btn" aria-label="検索を開始">🔍</button> |
| 画像の alt | html<br><img src="{{ module.image.src }}" alt="{{ module.title | escape }}"> |
| 色コントラスト(CSS 変数) | scss<br>$primary-color: #004080;<br>$text-on-primary: #ffffff; // コントラスト比 4.5:1 以上<br>.hub-custom__button { background: $primary-color; color: $text-on-primary; } |
Tips:Chrome の DevTools → Lighthouse を実行すれば、上記項目のスコアが自動で測定できます。
Git ブランチ運用例(git‑flow)
|
1 2 3 4 5 |
main ← 本番環境 develop ← ステージング/統合ブランチ feature/xxx ← 新規テンプレートやモジュールの開発ブランチ release/v1.2 ← リリース前の最終調整ブランチ |
git checkout -b feature/custom-template- 開発 →
hs upload -p(ローカルプレビュー) → コミット & プッシュ - Pull Request を作成し、コードレビューと Lighthouse レポートを添付
developへマージ後、git checkout release/v1.2 && git merge develophs upload -pでステージングにデプロイ → 最終テスト実施- 問題なければ
mainにマージし、本番環境へプッシュ
このフローを守るだけで、品質保証 と 継続的デリバリー が実現します。
まとめ
- Design Manager + HubSpot CLI でローカル開発が安全かつ高速に行える。
- テンプレートは HTML+HubL、モジュールは module.json + module.html の組み合わせで再利用可能。
- カスタム CSS/JS は 名前空間化 と defer で CSP に対応しつつパフォーマンスを最適化。
- Functions は
hubspot.function("functionName")シンタックスで呼び出し、HubDB と組み合わせて動的コンテンツを提供できる。 - プレビュー・テストは CLI の preview コマンドと Git flow で管理し、SEO/アクセシビリティはメタタグ・構造化データ・ARIA など具体的実装例に沿ってチェックする。
これらのベストプラクティスを取り入れれば、HubSpot CMS 上で高度なカスタマイズが可能になるだけでなく、検索エンジン評価やユーザー体験も同時に向上させることができます。ぜひ本ガイドを開発プロジェクトの標準手順として活用してください。