スポーツ施設のWebサイトのSEO。テニス・フットサル・ゴルフ練習場など、種目とスクール・貸し出しが混ざる施設のページの分け方と、ビジネスプロフィールのカテゴリと部門、構造化データの型の決め方
テニスコート・フットサル・ゴルフ練習場など、
この
この
この
スポーツ施設のサイトは「施設」「種目」「使い方」の3段で組む
種目と
| 段 | ページの例 | 書くこと |
|---|---|---|
| 1. 施設 | トップ、 |
施設名・住所・電話・営業時間・駐車場、 |
| 2. 種目 | /tennis/、/futsal/、/golf/ | その |
| 3. 使い方 | /tennis/school/、/tennis/rental/、/futsal/rental/ | 対象・料金・時間 |
使い方は、
| 使い方 | 探す人が |
ページに |
|---|---|---|
| スクール | 対象の |
クラスごとの |
| 貸し出し | 空き、 |
料金表、 |
| 個人利用 | 料金、 |
料金、 |
| 大会・イベント | 日程、 |
開催日、 |
種目の
種目と使い方のページには、料金・空き・対象を文字で書く
料金表を
スクールの
貸し出しの
ビジネスプロフィールは、カテゴリ・部門・名前・営業時間の4つを先に決める
Googleマップに
ポイント1. カテゴリは「事業が何であるか」で、少なく選ぶ
Googleの
施設が
ポイント2. 部門のプロフィールは、独立した窓口があるときだけ作る
同じ
施設に
ポイント3. ビジネス名に、種目・地名・サービスを足さない
ガイドラインは、
ポイント4. 営業時間は、レッスンだけで決まる場合は設定しない
ガイドラインは、
構造化データは、施設全体の型と部門で書き、型の名前を確かめてから載せる
Googleのname と address のdepartment には、
スポーツ施設に
// schema-types.mjs
// schema.org の最新の語彙を取得し、SportsActivityLocation の下位の型を表示する
const URL = 'https://schema.org/version/latest/schemaorg-current-https.jsonld';
const res = await fetch(URL);
const { '@graph': graph } = await res.json();
const types = graph.filter((n) => [].concat(n['@type']).includes('rdfs:Class'));
const parentsOf = (id) => [].concat(types.find((t) => t['@id'] === id)?.['rdfs:subClassOf'] ?? []).map((p) => p['@id']);
const label = (id) => id.replace('schema:', '');
const chain = (id) => { const out = [id]; let p = parentsOf(id); while (p.length) { out.push(p[0]); p = parentsOf(p[0]); } return out.map(label).join(' < '); };
console.log('取得日時:', new Date().toISOString(), 'HTTP', res.status);
console.log(chain('schema:SportsActivityLocation'));
const children = types.filter((t) => parentsOf(t['@id']).includes('schema:SportsActivityLocation')).map((t) => label(t['@id'])).sort();
console.log('下位の型:', children.join(', '));
const dep = graph.find((n) => n['@id'] === 'schema:department');
console.log('department の domain:', [].concat(dep['schema:domainIncludes']).map((d) => label(d['@id'])).join(', '),
'/ range:', [].concat(dep['schema:rangeIncludes']).map((d) => label(d['@id'])).join(', '));$ node schema-types.mjs
取得日時: 2026-10-07T01:09:15.475Z HTTP 200
SportsActivityLocation < LocalBusiness < Organization < Thing
下位の型: BowlingAlley, ExerciseGym, GolfCourse, HealthClub, PublicSwimmingPool, SkiResort, SportsClub, StadiumOrArena, TennisComplex
department の domain: Organization / range: Organization(実際に
次に、DrivingRange)を
// facility-jsonld.mjs
// 施設の台帳(1か所)から、施設全体と種目ごとの部門の JSON-LD を作り、公開前に3つの点を確かめる
// 1) @type が schema.org に実在する型か 2) name と address があるか(Google の必須項目)
// 3) 部門の name が「施設名 部門名」の形か(Google のガイドの原則の書き方)
import { readFileSync } from 'node:fs';
const facility = JSON.parse(readFileSync(process.argv[2], 'utf8'));
const vocab = await (await fetch('https://schema.org/version/latest/schemaorg-current-https.jsonld')).json();
const known = new Set(vocab['@graph'].filter((n) => [].concat(n['@type']).includes('rdfs:Class')).map((n) => n['@id'].replace('schema:', '')));
const address = {
'@type': 'PostalAddress', postalCode: facility.postalCode, addressRegion: facility.region,
addressLocality: facility.locality, streetAddress: facility.street, addressCountry: 'JP',
};
const jsonld = {
'@context': 'https://schema.org',
'@type': facility.type,
'@id': `${facility.url}#facility`,
name: facility.name,
url: facility.url,
telephone: facility.telephone,
address,
department: facility.departments.map((d) => ({
'@type': d.type,
name: `${facility.name} ${d.name}`,
url: `${facility.url}${d.path}`,
telephone: d.telephone ?? facility.telephone,
address,
})),
};
const problems = [];
const check = (node, where) => {
if (!known.has(node['@type'])) problems.push(`${where}: @type「${node['@type']}」は schema.org にない`);
if (!node.name) problems.push(`${where}: name がない`);
if (!node.address?.streetAddress) problems.push(`${where}: address がない`);
};
check(jsonld, '施設');
jsonld.department.forEach((d, i) => {
check(d, `部門${i + 1}(${d.name})`);
if (!d.name.startsWith(`${facility.name} `)) problems.push(`部門${i + 1}: name が「施設名 部門名」の形でない`);
});
console.log(JSON.stringify(jsonld, null, 2));
console.log(problems.length ? `確かめること ${problems.length}件:\n- ${problems.join('\n- ')}` : '確かめること 0件');台帳
{
"name": "みなとスポーツパーク",
"type": "SportsActivityLocation",
"url": "https://example.com/",
"telephone": "+81-78-000-0000",
"postalCode": "650-0000",
"region": "兵庫県",
"locality": "神戸市中央区",
"street": "(例)港町1-2-3",
"departments": [
{ "type": "TennisComplex", "name": "テニスコート", "path": "tennis/" },
{ "type": "SportsActivityLocation", "name": "フットサルコート", "path": "futsal/" },
{ "type": "DrivingRange", "name": "ゴルフ練習場", "path": "golf/" }
]
}出力の
$ node facility-jsonld.mjs facility.json
{
"@context": "https://schema.org",
"@type": "SportsActivityLocation",
"@id": "https://example.com/#facility",
"name": "みなとスポーツパーク",
…
"department": [
{
"@type": "TennisComplex",
"name": "みなとスポーツパーク テニスコート",
"url": "https://example.com/tennis/",
…
確かめること 1件:
- 部門3(みなとスポーツパーク ゴルフ練習場): @type「DrivingRange」は schema.org にない存在しない
部門を
やってはいけないこと
検索や
例1. 種目×地名のページを量産する
「〇〇市 テニスコート」
例2. 設備を並べるためにカテゴリを増やす
プールや
例3. ビジネス名に種目や「駅前」を入れる
ビジネス名に
公開した後は、種目ごとの検索語と着地ページを確かめる
公開した
公開前に確かめること
サイトと
- 種目ごとに
1ページあり、 その 下に 使い方 (スクール・貸し出し・個人利用)の ページが ある - 料金は
画像だけでなく 文字の 表で 書き、 時間帯・ 曜日・会員の 区分が 分かる - 予約の
方法・ 受付の 開始・取り消しの 期限・雨天の 扱いを、 予約の 画面に 入る 前に 読める - スクールは
クラスごとに 対象・曜日・定員・月謝・振替が 書いてある - 地名だけを
入れ替えた ページが ない - ビジネスプロフィールの
カテゴリは 「事業が 何であるか」で 選び、 設備の カテゴリを 足していない - 部門の
プロフィールは、 窓口・営業時間・カテゴリが 別の ものだけ - ビジネス名は
看板どおりで、 種目・地名・サービスを 足していない - 構造化データの
型の 名前を schema.org の 語彙と 照らし、 部門の 名前は 「施設名 部門名」に なっている - 構造化データに
書いた 部門・住所・電話が、 ページの 本文にも 載っている
自社でやる場合と、任せる場合
自社で
任せる
出典(一次情報)
2026年10月7日に
- Google ビジネス プロフィールの
ガイドライン :ビジネス名に(Google ビジネス プロフィール ヘルプ) 含めてはいけない 情報、 営業時間を 指定しない ビジネス、 カテゴリの 選び方と 例、 ビジネス・大学・機関内の 各部門 - 店舗情報
(LocalBusiness)の :具体的な構造化データ (Google 検索セントラル) 下位の 型を 使う、 必須の プロパティ (name・address)、 department と 部門の 名前の 書き方 (2026-09-12 更新) - 構造化データに
関する :表示されない一般的な ガイドライン (Google 検索セントラル) コンテンツを マークアップしない、 ページの コンテンツを 正確に 表す (2026-09-16 更新) - スパムに
関する :誘導ページのポリシー (Google 検索セントラル) 不正使用の 定義と 例(2026-09-02 更新) - SportsActivityLocation
(schema.org) 、schema.org の最新の :下位の語彙ファイル (JSON-LD) 型の 一覧と department の 定義 (2026年10月7日に 取得)
よくある質問
テニスもフットサルもある施設は、ビジネスプロフィールのカテゴリを種目の数だけ付ければよいですか?
付けません。
テニススクールやゴルフ練習場を、施設とは別のビジネスプロフィールにできますか?
対外的に
スポーツ施設の構造化データは、どの型を使えばよいですか?
Googleの
近くの市や駅の名前ごとに、種目のページを作ってもよいですか?
おすすめしません。
