サンクスページは 1 枚でいい — HubSpot Starter のページ枠を節約する実装
最終更新日: / 公開日:
最終更新日: / 公開日:
本記事のポイント
- 同じ URL のサンクスページから資料ごとに違う PDF が落ちてくる仕組みを検証したところ、URL のパラメータは分岐に使われておらず、サーバーがセッションを見てリンクを差し込んでいました
- Content Hub Starter のページ枠は、2026 年 7 月時点の新規契約でウェブサイトページ 30、ランディングページ 30 です。資料やウェビナーは 1 本増やすたびに告知 LP とサンクスページの 2 枚セットで枠を使うため、10 本走らせると 20 枚が消えます
- 1 枚のページ + クエリパラメータ + カタログで出し分ければ、ページ枠の消費は 1 枚です。コードと、HubSpot 固有の落とし穴 3 つをそのまま持ち帰れます
「資料が増えるたびにサンクスページを作っていて、ページの枠が心配です」。HubSpot Content Hub Starter を使っている支援先から、たびたび出てくる話です。
きっかけは、国内のある BtoB サイトの資料ダウンロード導線でした。どの資料に申し込んでもサンクスページの URL は同じで、末尾のパラメータだけが違う。それなのに、ボタンを押すと申し込んだ資料の PDF が落ちてきます。
本記事では、その仕組みを検証した結果と、同じ考え方を HubSpot でページ枠を消費せずに実装する方法を解説します。特別な権限もプランのアップグレードも不要です。
1. 同じ URL なのに、違う資料が落ちてくる
観察したのは、資料ダウンロードのサンクスページです。どの資料に申し込んでも遷移先は同じパスで、違うのは末尾に付く ?submissionGuid=26572eef-... のようなパラメータだけでした。
このパラメータは、HubSpot のフォームが送信後のリダイレクトに自動で付けるものです。送信レコードの識別子にあたります。
素直に考えれば、この GUID をキーにサーバーで資料を引いているという推測になります。実際に確かめると、違いました。
2. 検証 1 — パラメータは分岐に使われていなかった
最初にやったのは、パラメータを壊してみることです。
- パラメータを消して、サンクスページのパスだけでアクセスする
- 存在しない GUID (
00000000-0000-0000-0000-000000000000) に差し替えてアクセスする
どちらもボタンのリンク先 PDF は変わりませんでした。つまり GUID は出し分けに使われていません。
これは HubSpot の設定側からも裏付けが取れます。埋め込まれているフォームの定義を確認すると、資料 6 本ぶんのフォームはリダイレクト先がすべて同じ URL で統一されており、どの資料かを示す隠しフィールドもありませんでした。
HubSpot 側は「全フォーム同じ場所に送る」だけの設定です。分岐はサイト側で起きています。
3. 検証 2 — 正体は「直前に見た資料ページ」だった
次に、サンクスページの HTML を Cookie を送らずに取得しました。返ってきたボタンは、こうなっていました。
<a download target="_blank">会社案内をダウンロード</a>
href 属性そのものがありません。Cookie を送ると、同じ位置に PDF の URL が入った状態で返ってきます。
JavaScript による書き換えではありません。テーマの JS にもタグマネージャーのコンテナにも、PDF のパスは 1 つも含まれていませんでした。サーバー側で HTML を組み立てる段階で差し込まれています。
どの Cookie が効いているのかを 1 つずつ潰していくと、答えは PHPSESSID の 1 つだけでした。
| 送った Cookie | ボタンの href |
|---|---|
| なし | 属性ごと存在しない |
PHPSESSID だけ削除 |
属性ごと存在しない |
PHPSESSID を元に戻す |
PDF の URL が入る |
PHPSESSID 以外を削除 |
変化なし |
決定的だったのは次の挙動です。資料ページ A を読み込んだ直後にサンクスページを取得すると資料 A の PDF、資料ページ B の直後だと資料 B の PDF に変わりました。
つまり「直近に閲覧した資料ページ」をサーバーのセッションに記録して、サンクスページでそれに紐づく PDF を出力しているだけの実装です。フォームを送信していなくても、資料ページを 1 回開けば記録されます。

この設計のうまさは、HubSpot 側の設定が「全フォーム同じリダイレクト先」だけで済むことです。フォームを増やしても HubSpot の設定作業は増えず、サンクスページも 1 枚のまま。計測も URL が 1 本に集約されて素直になります。
一方で、割り切られている点もあります。フォーム未送信でもダウンロードに到達できること、PDF 自体は直リンクで取得できること、セッション依存なのでページキャッシュと相性が悪いことです。
リード獲得の実務では「PDF は公開でよい、フォームは接点を作るためのもの」と割り切る判断は十分あり得ます。ただ真似するなら、意図してその判断をしたほうがいいと思います。
4. ここからが本題 — Starter のページ枠は 30 ずつ
さて、この「サンクスページは 1 枚、中身だけ出し分ける」という発想は、Content Hub Starter を使っている人にとって小技以上の価値があります。
まず枠を正確に把握します。
| 種類 | Content Hub Starter | Professional |
|---|---|---|
| ウェブサイトページ | 30 | 10,000 |
| ランディングページ | 30 | — |
| ブログ | 1 つ (サイトと同じサブドメイン) | 100 |
| ブログ記事 | 最大 10,000 本 (上の枠には含まれない) | 各ブログ 10,000 本 |
ブログ記事はページ枠を消費しません。Starter でも 10,000 本まで書けるので、記事数で詰まることはまずないはずです。ただしブログそのものは 1 つしか持てないため、オウンドメディアと採用ブログを分けたいといった要望は Starter では通りません。
ここで 1 つ注意があります。Starter のページ上限は契約した時期によって違います。上の数字は 2026 年 7 月時点で新規に契約した場合の値で、以前に契約したアカウントでは 50 ずつのケースがあります。自社がどちらなのかは、管理画面のページ一覧で確認してください。
humbulls のアカウントは 50 ずつの世代ですが、実際に API がエラーを返すところまで試して分かったことがあります。アーカイブ済みのページも枠を消費することです。使わなくなったページを非公開にしただけでは、枠は戻りません。

本来のスマートな解は、HubDB や CRM オブジェクトを使った動的ページです。ただしこれは Content Hub Professional 以上の機能で、Starter では使えません。サーバーレス関数に至っては Enterprise が必要です。
つまり Starter では、限られた枠をどう使うかが勝負になります。ここで効いてくるのが、施策の増え方です。
資料やウェビナーは、1 本増やすたびに告知 LP とサンクスページの 2 枚セットで枠を使います。資料 5 本とウェビナー 5 本を走らせれば、それだけで 20 枚です。LP 枠 30 のうち 3 分の 2 が、施策 10 本で埋まります。
サンクスページを 1 枚に畳めば、この 20 枚が 11 枚になります。減るのは 9 枚ですが、増え方が変わるのが大きいところです。施策を 1 本足したときの消費が 2 枚から 1 枚になり、以降は告知 LP のぶんしか増えません。

そこで「1 枚のページ + クエリパラメータ + カタログ」で、見た目上の枚数を増やします。ページ上限にカウントされるのは 1 枚だけです。
Starter で何ができて何ができないかの全体像は、HubSpot Starter の制限一覧 — 30 の壁と回避可否を全整理で整理しています。
5. HubSpot での実装 — クエリパラメータ + カタログ方式
検証したサイトと同じセッション方式を HubSpot で再現するのは筋が悪いので、クエリパラメータでやります。
フォーム側の設定
フォームの送信後アクションで「Redirect to a page, URL...」を選び、クエリ付きの URL を直接入力します。この機能に上位プランは要りません。
https://example.com/thanks?doc=works
回答内容による条件分岐リダイレクトは上位プランの機能ですが、フォーム 1 本につきリダイレクト先が 1 つで足りるので不要です。資料ごとにフォームを分け、それぞれ違う doc の値を付けるだけです。
プリレンダリングを壊さないための鉄則
ここが HubSpot 固有の落とし穴です。HubL の request.query や request.query_dict はプリレンダリングに対応しておらず、使うとそのページが CDN にキャッシュされなくなります。request.cookies や request.path_and_query も同じ扱いです。
HubSpot 自身も、動的な出し分けはできるかぎりクライアントサイドで行うよう案内しています。HubL で分岐せず、JavaScript で location.search を読みます。
資料カタログはモジュールの repeater フィールドに持たせ、公開時に |tojson で JSON として JS に埋め込みます。HubL は公開時に評価されるだけなので、プリレンダリングは壊れません。
モジュールのフィールド定義
[
{
"name": "items",
"label": "資料カタログ",
"type": "group",
"occurrence": { "min": 1, "max": 50 },
"children": [
{ "name": "key", "label": "キー (URL の doc= の値)", "type": "text" },
{ "name": "label", "label": "ボタン文言", "type": "text" },
{ "name": "file", "label": "PDF ファイル", "type": "file" }
]
},
{ "name": "fallback_url", "label": "既定の資料 URL", "type": "file" },
{ "name": "fallback_label", "label": "既定のボタン文言", "type": "text" }
]
モジュールの HTML
<a id="dl-btn" href="" download target="_blank" rel="noopener">
</a>
<script>
window.DL_CATALOG = [
];
(function () {
var key = new URLSearchParams(location.search).get('doc');
var hit = window.DL_CATALOG.filter(function (i) { return i.key === key; })[0];
if (!hit) return; // 一致しなければ初期 HTML の既定資料のまま
var a = document.getElementById('dl-btn');
a.setAttribute('href', hit.url);
a.textContent = hit.label;
})();
</script>
資料が増えたときにやることは、モジュールの設定画面で行を 1 つ足し、フォームのリダイレクト先に ?doc= の値を書くことだけです。ページは増えません。

6. 実装の落とし穴 3 つ
この実装は短いのですが、外すと危ないポイントが 3 つあります。
URL から受け取った値を href に入れない
?file= でパスを直接渡す設計にすると、外部 URL や javascript: スキームを流し込まれます。照合するのはカタログ内のキーだけにして、URL はモジュール設定側の値を使います。
ボタン文言の差し替えも textContent で行い、innerHTML は使いません。カタログにない値が来たら、何もせず既定の状態を保ちます。
初期 HTML に既定のリンクを入れておく
JavaScript の役割は「上書き」です。初期状態の HTML に既定資料のリンクを書いておけば、JS が落ちてもボタンは死にません。
検証したサイトの実装は href が空になるパターンがあり、セッションが切れているとボタンが無反応になります。初期値を持たせておけば、この失敗は避けられます。
パラメータの数や順序に依存しない
HubSpot は submissionGuid を自動で足してきますし、広告経由なら UTM パラメータも付きます。文字列を自前で切り出す実装にすると、パラメータが増えた瞬間に壊れます。
URLSearchParams で目的のキーだけを読めば、順序や個数が変わっても影響を受けません。
公開後の確認
実装したら、URL に ?hsDebugOnly=true を付けて読み込みます。プリレンダできるかどうかと、できない場合は阻害要因がファイル名と行番号つきで表示されます。
あわせてレスポンスヘッダに X-HS-Prerendered が出ることを確認してください。出ていなければ、どこかにクエリ依存の HubL が残っています。
7. 計測と SEO、この手が向かないケース
計測は、ボタンのクリックで dataLayer にイベントと資料キーを積み、タグマネージャー側で拾うのが素直です。URL が 1 本に集約されるぶん、ページビューは合算されます。資料別に見たいときはイベントのパラメータで分けます。
SEO については、HubSpot が canonical をクエリなしの URL に寄せるため、?doc= の違いで重複インデックスされる心配はありません。そもそもサンクスページは noindex にしておくべきページです。
同じ手は、サンクスページ以外にも効きます。
- 業種別・職種別に訴求文だけ変えたい LP
- キャンペーンごとの完了画面
- ステップメールの遷移先
レイアウトが同じで、差分がテキストとリンクだけのページは、まとめて 1 枚に畳めます。
逆に向かないのは、検索流入を取りたいページです。クエリパラメータ違いは canonical で 1 本に寄るので、個別に順位を取ることはできません。ここを畳むと集客が止まるので、素直にページを作るか、プランを上げる判断になります。
もうひとつ、ダウンロードを本当にゲートしたい場合も、この方式では守れません。URL を知っていれば誰でも到達できます。その場合はフォーム送信後にメールで資料リンクを送る方式に切り替えるのが現実的です。
なお Professional 以上に上げると、動的ページという正攻法が使えるようになります。動的ページが生成した子ページはページ上限にカウントされないため、100 件生成してもテンプレート 1 枚として数えられます。ページ数が本格的に必要になったときの移行先は、そちらです。
まとめ
検証したサンクスページの正体は、URL のパラメータによる出し分けではありませんでした。直近に見た資料ページをセッションに記録して、サーバーがリンクを差し込んでいるだけの実装です。
- 本質は実装方式ではなく「サンクスページは 1 枚でいい」という設計判断のほうです
- Content Hub Starter の枠は、いまの新規契約でウェブサイトページ 30、ランディングページ 30。契約時期で違ううえ、アーカイブしても枠は戻りません
- 1 枚のページ + クエリパラメータ + カタログなら、ページ枠の消費は 1 枚で済みます
まずは自社のサンクスページが何枚あるかを数えてみてください。3 枚以上あるなら、1 枚に畳める可能性が高いです。
Starter のまま、どこまでサイトを作れるかの全体像は HubSpot Starter 完全ガイド — 機能・制限・活用の全ノウハウにまとめています。ページ枠を見ながらサイトを育てる進め方は、サービスサイトの段階公開 — リード獲得と並走する 4 フェーズ設計が参考になります。
HubSpot の設計から実装まで一緒に進めたい場合は、humbulls の Growth Partner サービスで伴走しています。BtoB マーケティング全体を整理したい方は BtoB マーケティング AI 活用ガイドもご活用ください。
参考文献
- Create and customize pages — HubSpot ナレッジベース (取得日: 2026-07)
- Build dynamic pages using HubDB — HubSpot developers (取得日: 2026-07)
- Build dynamic pages using CRM objects — HubSpot developers (取得日: 2026-07)
- Prerendering — HubSpot developers (取得日: 2026-07)
- Serverless functions overview — HubSpot developers (取得日: 2026-07)