Bisher haben wir unsere Applikation immer so gebaut, dass ein Crawler den wichtigen Inhalt auch im Quelltext vorfindet. Das führt insbesondere bei modernen Webseiten (z.B. durch die Nutzung von AJAX und dynamischem Austausch von Inhalten) zu Mehraufwand, weil sichergestellt werden muss, dass neben dem Client auch der Server das HTML rendern können muss. Es gibt einige Ansätze, die das Problem serverseitig lösen – z.B. PhantomJS – aber es führt unweigerlich dazu, dass sich der Aufwand für SEO massiv erhöht.
Bereits seit längerer Zeit wird gemunkelt, dass Google während dem Indexieren von Webseiten auch JavaScript ausführen würde. Im Mai 2014 klärte ein Post im offiziellen Google Webmaster Blog auf: Google führt tatsächlich JavaScript aus! Was möglich ist, wurde unter anderem in einem Artikel auf searchengineland.com genau untersucht. Wir haben uns entschieden, die neuen Möglichkeiten mit einer bestehenden AngularJS-Applikation zum Darstellen von Referenzen zu testen. Es waren einige Anpassungen nötig, aber wertvoll: Google hat die Inhalte mittlerweile korrekt indexiert (inkl. Seitentitel, Meta-Description, Bilder, …). Es ist also möglich, eine moderne Webseite mit dynamischen Inhalten einwandfrei von Google indexieren zu lassen, auch wenn das HTML erst auf dem Client generiert wird.
Folgende Schritte waren nötig (ausgehend von einer funktionierenden AngularJS-App):
- ngRoute einbinden – ein AngularJS-Modul, welches das view-routing löst
- Applikation in Views aufteilen – z.B. Listenansicht, Detailansicht etc. und das Routing einrichten (routeProvider)
- html5Mode für ngRoute aktivieren (ohne diesen Modus wird nicht mit HTML5 pushState gearbeitet, sondern mit Hash # – so werden die Seiten bei Google nicht korrekt indexiert) – mehr dazu hier
- Links anpassen: Alle Links zwischen den Views der Applikation müssen als Links ohne Hash angegeben werden: z.B. <a href=“/referenzen/id/289/seo-fuer-javascript-applikationen-mit-angularjs“>Zum Beitrag</a> (wobei /referenzen in unserem Beispiel die Hauptseite für die Referenzen war)
- Base-Tag einfügen <base href=“/referenzen/“> – dieser muss sich innerhalb des ng-app Knotens befinden
- Sicherstellen, dass der Server dasselbe liefert für alle „Unterseiten“ von /referenzen (denn Google wird jede verlinkte Seite besuchen, zudem ermöglicht man so das direkte Verlinken auf spezifische Views)
- Testen der Seite in allen relevanten Browsern – Insbesondere IE 9 muss getestet werden, weil dieser pushState nicht unterstützt. Es wird stattdessen mit Hash-Links gearbeitet (z.B. /referenzen/#/id/289/beispiel-titel).
Eine wichtige Erkenntnis war auch, dass man Google per JavaScript einen neuen Titel für die Seite zuweisen kann ($window wird dem ngController via dependency injection als Abhängigkeit mitgegeben):
$window.document.title = currentReference.title;
Der Titel wird jedes Mal angepasst, wenn die Route sich ändert. Google nimmt den veränderten Titel mit in die Suchresulate auf. Auch Weiterleitungen folgt Google (via document.location.href = ‚…‘).
Wichtig: Viele Suchmaschinen unterstützen JavaScript nicht (Google ist anderen einen Schritt voraus). Diese haben keine Möglichkeit, den Inhalt zu indexieren. Wir hoffen dennnoch, eure Neugierde geweckt zu haben, das auch mal auszuprobieren.
Viel Spass!
Raphael Müller, 2sic internet solutions GmbH