Duplicate Titles bei der Seitennummerierung

Dieser Artikel geht mehr in Richtung SEO. Denn als Entwickler sollten wir natürlich auch die Basics einer guten Suchmaschinen-Optimierung kennen und gleich von vornherein umsetzen.

Also angenommen wir haben einen Online-Shop mit einer Vielzahl an Produkten. Alle auf einer Seite anzuzeigen ist erstens unübersichtlich und zweitens hinsichtlich der SEO nicht ratsam. Überprüft man seine Onpage Optimierung mit einem Tool (z.B. Xovi), wird einem der Hinweis angezeigt dass zu viele Interne Links auf einer Seite bestehen. Klar - alle Links zu den Produkten. Das ist bei wenigen sicher kein Problem, bei mehreren hundert jedoch schon. Google könnte das als "Link Farming" Werten.

Pagination

In Laravel können wir es uns einfach machen, wir nutzen einfach die Pagination . Mit folgendem Beispiel teilen wir unsere Übersichtsseite in Einzel-Seiten mit jeweils 25 Produkten auf.

// ProductsController.php

public function index() {
    $products = Product::paginate(25);
    return view('products.index', compact('products'));
}

In der Blade View geben wir sie wie gewohnt aus. In einem echten Projekt würde man noch ein Produktbild und weitere Informationen darstellen. Ich begnüge mich hier mit einer einfachen Liste.

// products/index.blade.php

<h1>Produkte</h1>
<ul>
@foreach($products as $product)
    <li>
        <a href="{{ route('products.show', $product->id) }}">{{ $product->name }}</a>
    </li>
@endforeach
</ul>

{{ $products->render() }}

Um die Links zu unseren einzelnen Seiten anzuzeigen verwenden wir {{ $products->render() }}. $products ist in diesem Fall nicht die Collection unserer Produkte, sondern ein Paginator-Objekt mit zusätzlichen Informationen (wie z.B. die aktuelle Seite, Anzahl der Items, den Items selbst und noch mehr). Das wars auch schon. Unsere Produkte werden nun zu jeweils 25 Stück auf Einzelseiten ausgegeben.

Probleme mit der SEO

Kommen wir nun zum Teil der Suchmaschinen-Optimierung. Im wesentlichen gibt es folgende Probleme:

Duplicate Content

Um das Problem mit der ersten Seite zu vermeiden setzen wir einen Canonical Link. Der zeigt an dass das Original der angeforderten Seite eine bestimmte URL hat.

Für die ganzen Meta Tags verwende ich gerne sections. So habe ich den Inhalt schön in meiner View und muss die Inhalte der Tags nicht im Controller setzen.

// products/index.blade.php
@section('meta')
    @if($products->currentPage() == 1)
        <link rel="canonical" href="{{ route('products.index') }}"/>
    @endif
@stop

Duplicate Titles

Dieses Problem ist rel. einfach zu lösen. Wobei, ehrlich gesagt bin ich mir gar nicht sicher ob das für google tatsächlich so relevant ist, wenn wir das dritte Problem gelöst haben.

Wir lassen einfach die Seitenzahl mit im Titel erscheinen:

// products/index.blade.php
@section('title', 'Unsere Produkte | Seite '.$products->currentPage())

Logische Verknüpfung

Wie schon angedeutet denke ich dass die Duplicate Titles kein Problem für Google sind, wenn eine logische Verknüpfung zwischen den Einzelseiten besteht. Dafür verwenden wir die rel='next' und rel='prev' Tags. Für jede Seite mit einer Folge- oder vorherigen Seite lassen wir entsprechenden Tag anzeigen. Damit weiß Google dass es sich um eine Seitendarstellung einer bestimmten Menge an Objekten handelt.

// products/index.blade.php
@section('meta')
    @if($products->previousPageUrl())
        <link rel="prev" href="{{ $products->previousPageUrl() }}" />
    @endif
    @if($products->nextPageUrl())
        <link rel="next" href="{{ $products->nextPageUrl() }}" />
    @endif
@stop

Anmerkung: wir müssen natürlich den oberen Canonical Link auch in die Meta-Section einbauen - ich hab das nur wg. der Übersicht rausgelassen.

Zusammenfassung

Unsere drei SEO Probleme haben wir nun gelöst. Es gibt keinen Duplicate Content für die erste Seite mehr, die Duplicate Titles sind eliminiert und die Einzelseiten sind logisch Verknüpft.

Hier nochmal das Blade Layout File. In einem echten Projekt wären natürlich noch CSS und Script Dateien eingebunden.

// layouts/main.blade.php

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">

    <title>@yield('title', 'Mein Online Shop')</title>
    <meta name="description" content="@yield('description', '')">

    // More Meta Tags
    @yield('meta')
</head>
<body>
    @yield('contents')
</body>
</html>

weitere Informationen