見出し画像

SEO対策で構造化マークアップをしてみよう!


はじめに

Hello World!あけましておめでとうございます!
akippaバックエンドエンジニアの杉山です。
昨年は皆様、本当にありがとうございました!今年もakippaを何卒よろしくお願いします!

さて、私は先年の5月からakippaに入社していますので1月時点で9ヶ月になります。
あっという間でしたが色々なタスクに取り組めて大変充実した年でした。

今年はさらに大きめのタスクを担当しますので気を引き締めていきます!
絶賛頭を悩ませながら新機能の設計作業中です。(あれこれ考える必要があるので、なんとか脳みそを振り絞って頑張っています…)
しっかりリリースをしてakippaのプロダクトも自分自身も成長させたいものです。

さて今回の記事は振り返りも兼ねて昨年中に取り組んだタスクの中で、経験ほぼ無しから実装まで対応したSEOのお話です。
誰かの参考になれば幸い。
それではよろしくお願いします。

SEOとは

そもそもSEOって何ですか?

皆さんはSEOについてご存知でしょうか?
「あー、あの会社の偉いトップの人でしょ?」…それはCEOです
「財務の担当責任者だっけ?」…それはCFOです
「AREやな!」…阪神!(「Aim!」・「Respect!」・「Empower!」の略語らしいですね…関西のセンスを感じる)

略語は本来の意味を失う

村上龍「五分後の世界」

略語を使いすぎるのも考えものか?
(SEOは海外生まれの概念なのでしょうがないところもありそうですが)

少し話がズレましたが、SEOは「Search Engine Optimization」の略語、日本語訳すると検索エンジン最適化になります。
Googleなどの検索エンジンランキングで上位になるように、ひいてはユーザーが流入しやすくなることを目的としています。
今回はその中でもテクニカルな面、コードに手を入れることで最適化を考えるということについてお話していきます。

構造化マークアップを施すとどうなる?

今回は構造化マークアップを施してリッチリザルトを設定してみましょう。
構造化マークアップを行うと、クローラーにページの情報を伝えることができます。
下記画像の枠部分を御覧ください。

zozoで検索した結果

検索窓が設定されていますね。
クローラーがマークアップから情報を読み取り、こんな感じで検索結果にプラスアルファの情報や機能を表示してくれます。(後述しますがGoogleのさじ加減もあるので、絶対に表示されるというわけではないのですけれど…)

検索結果ランキングに直接影響はないものの、ユーザーの目を引いたり機能性が上がるなど間接的にSEOに好影響を与えるので、ぜひやっておきたい対応です!

進め方

最適化するページを決める

まずはGoogleのドキュメントを読んでみて、どのページで構造化マークアップができそうかを見てみましょう。
akippaでも候補は色々ありますが…駐車場詳細のページでマークアップしてみましょう。

今回の例では名古屋が誇るスーパービル「ミッドランドスクエア」の駐車場を使わせて頂きましょう!
話がめちゃくちゃ脱線しますが、ミッドランドスクエアの展望台から見る夜景は超オススメ!ぜひこの駐車場を使って観に行ってください!
ただしクリスマスシーズンに一人で行くと、カップルだらけで精神的ダメージを受けるぞ!そこだけ要注意だ!(実際、私はやられたことがある)

駐車場詳細
レビューもあります

駐車場詳細のページは駐車場の基本情報およびレビュー等から成り立っています。
ここには貼っていませんが、ページ下部にはカードリスト形式のおすすめ駐車場一覧やパンくずリストもあります。
あくまでも今回はお試しということで、とりあえず基本情報とレビューの構造化マークアップをしてみましょう!

構造化マークアップの具体的な方法

公式ドキュメントで書かれているようにマークアップにはJSON-LDが推奨されています。
他の記述方法もありますがここは素直に推奨に従っておきましょう。
akippaではLaravelをフレームワークに使用しているので、該当ページのbladeファイルに<script>を埋め込めば良いという訳です。
それではまずは基本情報から!

<script type="application/ld+json">
    {
        "@context": "https://schema.org/",
        "@type": "Place",
        "name": "{{ $parking->name()->toString() }}",
        "address": "{{ $parking->address()->toString() }}",
        "url": "{{ URL::current() . $parking->id()->toString() }}",
        "description": "{{ $parking->areaInfo()->toString() }}",
        "openingHours": "{{ $parking->openTime()->startTime()->toString() }}-{{ $parking->openTime()->endTime()->toString() }}",
        "image": [
            "{{ $parking->images()->image1()->toString() }}",
            "{{ $parking->images()->image2()->toString() }}"
        ]
    }
</script>

こんな感じですね。
bladeファイルにPHPから取得したデータを使う形にしており、動的生成が必要なページではこのようにする必要があります。

また今回のような1ページ1情報といった形ならviewページを表示する際に、Controllerから渡した変数を展開するだけですが、複数の情報を使用するパターン(例えば個別レビューがいくつかあるページ)の場合は、blade内でループ展開してからそれをJSONエンコードする必要があります。

どのようなプロパティが設定できるかはこのページを参照頂ければ。
今回は@typeをPlaceで設定しているので上記リンクを見れば良いですね!
駐車場の名称や住所、あとは画像などを構造化しています。

さて、上記で基本情報はOKとして次はレビューの部分に取り掛かりましょう!
これも公式のドキュメントが参考になります。
クチコミ抜粋の構造化データを見れば具体的な方法まで記載されています。
やっぱりGoogleは神。
ここではレビューの統計(AggregateRating)で構造化マークアップをします。

<script type="application/ld+json">
    {
        "@context": "https://schema.org/",
        "@type": "Place",
        "name": "{{ $parking->name()->toString() }}",
        "address": "{{ $parking->address()->toString() }}",
        "url": "{{ URL::current() . $parking->id()->toString() }}",
        "description": "{{ $parking->areaInfo()->toString() }}",
        "openingHours": "{{ $parking->openTime()->startTime()->toString() }}-{{ $parking->openTime()->endTime()->toString() }}",
        "image": [
            "{{ $parking->images()->image1()->toString() }}",
            "{{ $parking->images()->image2()->toString() }}"
        ],
        "aggregateRating": {
            "@type": "AggregateRating",
            "itemReviewed": {
                "@type": "LocalBusiness",
                "image": "{{ Config::get('akippa.front.resource.image') . '/icon/car-gray.svg' }}",
                "address": "{{ $parking->address()->toString() }}",
                "name": "{{ $parking->name()->toString() }}"
        },
        "ratingValue": "{{ $parking->rating()->point() }}",
        "reviewCount": "{{ $parking->rating()->count() }}"
        }
    }
</script>

これでよしと。

リッチリザルト テスト

記載したから終わり!…とはならないのがこの世界。
テストをして構造が間違っていないかを確認する必要があります。
上記で記述したのはbladeファイルなので、テストするのは実際に生成されたhtmlで行う必要があります。
ブラウザの開発者ツールを使って該当の箇所をコピーしておきましょう。

テストにはこれまたGoogle神が公式に提供しているリッチリザルト テストを使用します。
このページのコード欄に該当の構造化マークアップをペーストしてテスト実行すると…

リッチリザルトテスト結果

やったぜ!
一部DBに保持していないプロパティがあるので「重要ではない問題を検出しました」と出てますが、全体的にはリッチリザルトの対象となっていますね!

注意点

構造化マークアップをする際にはGoogleがサポートするプロパティの中で、必須プロパティになっているものをマークアップする必要があります。
例えば今回だとこれらが該当します。

さらに推奨プロパティについても可能な限りマークアップする方が、評価が高くなります。
ですので各ページでどのようなものがプロパティとしてマークアップできるか意識しておくことが大事ですね!

また、正しくマークアップを施しても、リッチリザルトの表示・非表示はGoogleが判定するのでその辺も考慮する必要があります。

おわりに

ここまで構造化マークアップによるSEO対策について書いてきました。
テクニカル手法でSEO対策を行うのは現在では当たり前になっています。
ただ、ユーザーに使ってもらうには検索してもらった後、つまりプロダクトやページそのものが魅力的でなければなりません。
(目立っても中身がポンコツでは…)
ですので、基本的な機能向上などで魅力的なプロダクトを作りつつ、SEO対策も同時に進めていくことが重要になります!

また、SEOは統計情報分析を組み合わせてはじめて真の力を発揮します。
SEOで流入が増えたのか、はたまたプロダクト施策がヒットして流入が増えたのか等も見極めていく必要もあるので、今回の対応はその入口に過ぎません。
とはいえ、今回の対応は決して無駄にはなっていないはず…(と思いたい)

マークアップ自体はドキュメントを見ながら進めれば難しいものではないですが、DBから取得したデータを加工する作業が必要な場面ではサーバサイドエンジニアとしての経験が活かせるなと思ったタスクでした!
今回はSEOの話になりましたがこれに限らず、これからも多くの方にakippaを利用してもらえるように鋭意努力して参ります!
改めてですが本年もakippaをよろしくお願いします!

この記事が気に入ったらサポートをしてみませんか?