SEO対策という言葉は広い。検索キーワードを考えることもSEOだし、ページの読み込みを速くすることもSEOに関係する。記事を書くこと、サイト構造を整理すること、HTMLを正しく出すこと、公開後にSearch Consoleを見ることも、それぞれSEOの一部になる。
だからWeb制作の現場では、「SEO対策をやる」とだけ言うと担当範囲がぼやける。サイト運営、ディレクター、デザイナー、コーダーで役割を分けるなら、コーダーがどこまで担うのかを切り分けておく必要がある。
この記事では、SEO対策の種類を整理したうえで、その中でコーダーに求められることをまとめる。最後に、よしあきが使っている静的サイト制作用テンプレートでは、現状どこまで対応しているかを確認する。WordPress 制作用テンプレートでの整理は 後編 に書いた。
SEO対策にはどんなものがあるか
SEO対策は、大きく分けると次のようになる。
コンテンツの対策
検索する人の疑問に答える本文を用意する領域。主にサイト運営、ディレクター、ライターの担当になる。
- 検索意図の整理
- キーワード調査
- ページごとのテーマ設計
- 見出しと本文の作成
- 事例、実績、FAQなどの追加
- 古い情報の更新
ここはコーダーが勝手に作る場所ではない。コーダーができるのは、決まった原稿や見出しを、検索エンジンにもユーザーにも読みやすいHTMLに落とすこと。
サイト設計の対策
サイト全体の構造を整える領域。
- サイトマップ設計
- URL設計
- ナビゲーション設計
- 内部リンク設計
- パンくずリスト設計
- 重複ページの整理
ここはディレクターの責任が大きい。ただし、実装のしやすさ、CMSでの管理方法、リンクの出力方法はコーダーも早めに確認した方がいい。
HTMLとメタ情報の対策
ページの意味をHTMLとして伝える領域。ここはコーダーの担当範囲にかなり近い。
titlemeta descriptionh1から始まる見出し構造alt属性- canonical
- OGP、Twitter Card
- 構造化データ
- クロール可能なリンク
ただし、titleやdescriptionの文言そのものはSEO方針に関わる。コーダーは「出力する仕組み」を作り、文言はディレクターや運営側と確認して入れるのがよい。
技術SEOとパフォーマンス
検索エンジンがページを取得しやすく、ユーザーが快適に見られるようにする領域。
- レスポンシブ対応
- 画像圧縮
- 画像サイズの適正化
width/height指定- lazy loading
- CSS、JavaScriptの読み込み最適化
- Webフォントの読み込み最適化
- 404、リダイレクト、noindex、robotsの確認
- HTMLのバリデーション
これはコーダーが主担当になりやすい。見た目を再現するだけではなく、公開後に検索エンジンが読みやすい状態まで整える。
運用と外部評価の対策
公開後に続ける領域。
- Search Consoleでの確認
- Google Analyticsなどでの計測
- コンテンツの追加、リライト
- SNSや外部メディアでの告知
- 被リンク、口コミ、紹介の獲得
ここはサイト運営側の比重が大きい。コーダーは計測タグの設置やイベント計測の実装など、運用の土台を支える。
コーダーに求められること
コーダーに求められるSEO対策は、ひと言でいうと「決まったSEO方針を、検索エンジンが読める実装に落とし込むこと」だと思う。
具体的には次のような範囲になる。
1. ページごとのメタ情報を正しく出す
ページごとにtitleとmeta descriptionを出し分ける。canonicalやOGPも同じページ情報から破綻なく出す。
静的サイトでもCMSでも、ページが増えるたびにheadを手作業でコピーする形にするとミスが出やすい。ページ情報をデータとして管理し、共通のheadから出力する形にしておくと、最低限のSEO設定を漏らしにくくなる。
2. HTMLの構造を整える
見出し、本文、リスト、表、リンク、画像を意味に合ったHTMLで書く。デザイン上の見た目だけでタグを選ばない。
特にコーダーが気をつけるのは、見出しの使い方、リンクの出し方、画像のalt、ボタンとリンクの使い分けあたり。アクセシビリティのための実装は、そのままSEOの土台にもなる。
3. 画像と表示速度を整える
画像が重いサイトは、ユーザー体験が悪くなる。コーダーは画像の圧縮、代替フォーマット、レイアウトシフト対策、遅延読み込みなどを実装する。
特にwidthとheightの指定は地味だが重要。画像の表示領域が先に確保されるので、読み込み中のガタつきを減らせる。
4. クロールしやすいリンクにする
ナビゲーション、フッター、パンくず、関連記事などは、ユーザーの導線であると同時にクローラーの導線でもある。
5. 検証できる状態にする
実装したら終わりではなく、ビルド、HTML検証、ブラウザ確認、PageSpeed Insights、リッチリザルトテストなどで確認する。
コーダーが担うSEOは「雰囲気」ではなく、出力結果で確認できる。最終的に本番HTMLがどうなっているかを見るのが大事。
コーダーが勝手に決めない方がいいこと
逆に、次のものはコーダーだけで決めない方がいい。
- 狙う検索キーワード
- titleやdescriptionの文言
- h1や本文の内容
- 画像が何を意味するか
- 新規ページを増やすかどうか
- どの導線を優先するか
- どの指標を改善目標にするか
コーダーは実装の専門家であって、事業や編集方針の責任者ではない。もちろん提案はしてよいが、最終判断はサイト運営やディレクターと揃える。
よしあきの静的サイトテンプレートで現状対応していること
実際によしあきの静的サイト制作用テンプレートを確認すると、コーダーが担うSEOの土台はかなり実装寄りに整えてある。
ページ情報を一元管理している
ラベル、パス、タイトル、説明文などを config/site.config.js の pages にまとめて持ち、各ページはキーを指定して ty_getPage で取り出す。イメージは次のとおりである(実際のフィールドやキーは案件に合わせて増減する)。
補足すると、ty_ はこのテンプレート内で使う自作ヘルパーの接頭辞である。JavaScript や EJS から呼ぶ関数を ty_getPage のようにしておくことで、標準 API や外部ライブラリの関数と見分けやすくしている。WordPress 版でも同じ考え方で、テーマ独自の PHP 関数に ty_ を付け、WordPress 本体やプラグインの関数と区別している。
// config/site.config.js の pages に登録しているイメージ(抜粋)
news: {
label: 'お知らせ',
root: '../',
path: 'news/',
title: 'お知らせ',
description: 'お知らせ一覧の説明文。',
keywords: 'お知らせ, 更新情報', // データとしては持てる
},
<% const key = 'news'; const page = ty_getPage(key); %>
<!DOCTYPE html>
<html lang="ja">
<%- include(ejsPath + 'common/_head.ejs', { page }) %>
<!-- … ヘッダー・本文 … -->
_head.ejs 側では、渡された page とサイト全体の baseUrl などから、次のように head を組み立てている(テーマ用スクリプト・フォント preload・CSS/JS の読み込みなどは省略)。
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title><%- page.title %></title>
<meta name="description" content="<%- page.description %>">
<meta property="og:url" content="<%- baseUrl + page.path %>">
<meta property="og:title" content="<%- page.title %>">
<meta property="og:description" content="<%- page.description %>">
<!-- … OGP の site_name / image、Twitter Card … -->
<link rel="canonical" href="<%- baseUrl + page.path %>">
<!-- … favicon、preload、stylesheet、script … -->
</head>
page に title や description が載るので、共通の _head.ejs から meta と title を一括出力できる。ページを増やすときも、まず pages に1件足すことになるため、設定の抜けに気づきやすい。
なお、keywords 用の項目はあってよいが、現状の head 出力では meta keywords としては出していない。Google はウェブ検索の順位付けに meta keywords を使わないと公式ヘルプで述べている。したがって、キーワード項目をそのまま meta keywords へ出さない構成とも矛盾しない。
共通headで基本メタを出している
共通headでは、次のような情報を出している。
- 文字コード
- viewport
titlemeta description- OGP
- Twitter Card
- canonical
- favicon、apple touch icon
- Webフォントのpreload
- CSS、JavaScriptの読み込み
SEOの基本メタとSNS共有の土台は、テンプレート側で共通化されている。ページごとに手でheadを書くよりも、案件全体で揃えやすい。
canonicalとOGP URLをページパスから組み立てている
base URLとページパスを使って、canonicalやOGP URLを組み立てている。静的サイトでありがちな「URLだけ古い」「OGPだけ別ページのまま」といったミスを減らせる設計になっている。
案件ごとにbase URLを正しく変えることは必要だが、仕組みとしてはSEO実装に向いている。
画像最適化がビルドに組み込まれている
ビルド時に画像圧縮が走り、設定に応じて WebP や AVIF のような代替フォーマットを生成できる。現在の設定では AVIF を使う形になっている。
そのうえで scripts/after-build.mjs が dist/ 配下の HTML を走査し、img に width / height を付け足したり、picture と source を補完したりする。CSS では、background-image や background の url(../images/...) のような形を検出できた場合に、JPEG をフォールバックにした image-set() を続けて出力する。
ソース側がたとえば単純な img だけでも、ビルド後は次のように近い見た目になるイメージである(ファイル名のハッシュやパスは案件・ビルド設定による)。
<!-- ソース(ビルド前)のイメージ -->
<img src="/assets/images/photo.jpg" alt="">
<!-- ビルド後処理後のイメージ(dist・代替画像が揃っている場合の例) -->
<picture>
<source srcset="./assets/images/photo-AbCd.avif" type="image/avif" width="1200" height="800">
<img src="./assets/images/photo-AbCd.jpg" alt="" width="1200" height="800">
</picture>
WebP は imageAltFormats を webp や both にしたときだけ生成され、上のような picture にも <source type="image/webp"> が増える。
CSS の背景は、dist 内の CSS において、単純な url(../images/foo.jpg) の background-image(または同形の background 略式)だけが対象になる。scripts/after-build.mjs が、元の1行を残したうえで続けて image-set() を足すイメージである。
/* dist 内の CSS・後処理前のイメージ */
.mv {
background-image: url(../images/mv-XyZ.jpg);
background-size: cover;
}
/* 後処理後(同じセレクタ内に image-set 用の background-image が増える) */
.mv {
background-image: url(../images/mv-XyZ.jpg);
background-image: image-set(
url(../images/mv-XyZ.avif) type("image/avif"),
url(../images/mv-XyZ.jpg) type("image/jpeg")
);
background-size: cover;
}
image-set() に含まれる候補も、imageAltFormats で有効な形式に合わせて増減する(例: AVIF のみなら AVIF と元画像の並びだけになる)。
これはコーダーのSEO対策としてかなり実務的だ。画像を置いたあと、人間が毎回寸法を調べて書く運用よりもミスが少ない。
HTML検証をビルドフローに入れている
本番ビルドとHTML検証をまとめて実行できるスクリプトがあり、コミット前の検証にも組み込まれている。
SEOだけを目的にした仕組みではないが、壊れたHTMLを減らすことは検索エンジンとユーザーの両方に効く。コーダーが品質を担保するための土台としてよい。
アクセシビリティ寄りの実装も入っている
ナビゲーションにはnavやaria-labelが使われ、ドロワーメニューにもaria-expandedやaria-hiddenなどが入っている。属性値に出す文字列を扱うためのヘルパーも用意されている。
アクセシビリティ対応はSEO対策そのものではないが、HTMLの意味を壊さず、ユーザーが使いやすいサイトにするという点でSEOの土台と重なる。
まだ個別対応が必要なこと
テンプレートに土台があっても、案件ごとに決める必要があるものは残る。
- 実際のtitle文言
- meta descriptionの文言
- h1や本文
- 画像の意味に合ったalt
- 構造化データを入れるかどうか
- noindexやrobotsの扱い
- Search ConsoleやAnalyticsの設定
- サイトマップの運用
- リダイレクト設計
robots.txt については、現状の静的テンプレート標準ではまだ生成・配置の仕組みを持っていない。案件ごとに src/public/robots.txt を置くのか、サイトマップの場所を明示するのか、noindex とどう切り分けるのかを決める必要があり、今後テンプレート側で標準化したい課題として残っている。
このあたりは、テンプレートだけで自動的に正解になるものではない。案件の目的、公開範囲、運用方針に合わせて決める。
まとめ
SEO対策は、コンテンツ、設計、実装、運用に分かれる。コーダーが中心的に担うのは、そのうち実装に近い部分だ。
よしあきの静的サイトテンプレートでは、ページ情報の一元管理、共通head、canonical、OGP、画像最適化、width / height自動付与、HTML検証といった、コーダー側で持つべきSEOの土台はすでに入っている。
一方で、キーワード、本文、見出し、altの意味、構造化データ、計測や運用方針は、案件ごとの判断が必要になる。
コーダーの役割は、SEOの全部を決めることではない。決まった方針を壊さず、検索エンジンとユーザーが読めるHTMLとして実装すること。そのためのテンプレートを育てておくことが、よしあきの現状のSEO対応だと整理できる。
関連記事
- SEO対策の全体像(WordPress版)— WPテンプレが担う土台と、プラグインに委ねる部分
- WordPress サイト制作の手順と、指定が無いときのよしあきルール … 構築・仕上げのなかでの SEO プラグインや自動生成 URL の位置づけ