it-swarm.com.de

Wie gehen Suchmaschinen mit AngularJS-Anwendungen um?

Ich sehe zwei Probleme mit der AngularJS-Anwendung in Bezug auf Suchmaschinen und SEO:

1) Was passiert mit benutzerdefinierten Tags? Ignorieren Suchmaschinen den gesamten Inhalt dieser Tags? Angenommen, ich habe

<custom>
  <h1>Hey, this title is important</h1>
</custom>

würde <h1> indiziert werden, obwohl es sich in benutzerdefinierten Tags befindet?


2) Gibt es eine Möglichkeit, Suchmaschinen daran zu hindern, {{}} Bindungen wörtlich zu indizieren? d.h.

<h2>{{title}}</h2>

Ich weiß, ich könnte so etwas tun

<h2 ng-bind="title"></h2>

aber was ist, wenn ich möchte, dass der Crawler den Titel "sieht"? Ist serverseitiges Rendern die einzige Lösung?

695
luisfarzati

Update Mai 2014

Google-Crawler führt jetzt Javascript aus - Sie können die Google-Webmaster-Tools verwenden, um besser zu verstehen, wie Ihre Websites von Google gerendert werden.

Ursprüngliche Antwort
Wenn Sie Ihre App für Suchmaschinen optimieren möchten, führt leider kein Weg daran vorbei, dem Crawler eine vorgerenderte Version zur Verfügung zu stellen. Sie können mehr über die Empfehlungen von Google für Ajax- und Javascript-schwere Websites lesen hier .

Wenn dies eine Option ist, würde ich empfehlen, diesen Artikel zu lesen, wie man SEO für Angular mit serverseitigem Rendering ausführt.

Ich bin nicht sicher, was der Crawler tut, wenn er auf benutzerdefinierte Tags stößt.

404
joakimbl

Verwenden Sie PushState und Precomposition

Die aktuelle Methode (2015), um dies zu tun, verwendet die JavaScript-Methode pushState.

PushState ändert die URL in der oberen Browserleiste, ohne die Seite neu zu laden. Angenommen, Sie haben eine Seite mit Registerkarten. Die Registerkarten verstecken und zeigen Inhalt und der Inhalt wird dynamisch eingefügt, entweder mit AJAX oder indem einfach display: none und display: block gesetzt werden, um den korrekten Inhalt der Registerkarten zu verbergen und anzuzeigen.

Wenn Sie auf die Registerkarten klicken, aktualisieren Sie die URL in der Adressleiste mit pushState. Verwenden Sie beim Rendern der Seite den Wert in der Adressleiste, um zu bestimmen, welche Registerkarte angezeigt werden soll. Angular Routing erledigt dies automatisch für Sie.

Vorkomposition

Es gibt zwei Möglichkeiten, eine PushState Single Page App (SPA) zu starten.

  1. Über PushState, wo der Benutzer auf einen PushState-Link klickt und der Inhalt AJAXed in ist.
  2. Indem Sie direkt auf die URL klicken.

Beim ersten Treffer auf der Website wird die URL direkt aufgerufen. Nachfolgende Treffer werden einfach im Inhalt AJAX angezeigt, wenn der PushState die URL aktualisiert.

Crawler sammeln Links von einer Seite und fügen sie dann zur späteren Verarbeitung in eine Warteschlange ein. Dies bedeutet, dass für einen Crawler jeder Treffer auf dem Server ein direkter Treffer ist und nicht über Pushstate navigiert wird.

Die Vorkomposition bündelt die anfängliche Nutzlast in der ersten Antwort vom Server, möglicherweise als JSON-Objekt. Auf diese Weise kann die Suchmaschine die Seite rendern, ohne den Aufruf AJAX auszuführen.

Es gibt Hinweise darauf, dass Google möglicherweise keine AJAX Anforderungen ausführt. Mehr dazu hier:

https://web.archive.org/web/20160318211223/http://www.analog-ni.co/precomposing-a-spa-may-become-the-holy-grail-to-seo

Suchmaschinen können JavaScript lesen und ausführen

Google ist seit einiger Zeit in der Lage, JavaScript zu analysieren. Aus diesem Grund haben sie ursprünglich Chrome entwickelt, um als voll funktionsfähiger Headless-Browser für den Google Spider zu fungieren. Wenn ein Link ein gültiges href-Attribut hat, kann die neue URL indiziert werden. Es gibt nichts mehr zu tun.

Wenn durch Klicken auf einen Link zusätzlich ein PushState-Aufruf ausgelöst wird, kann der Benutzer die Site über PushState navigieren.

Suchmaschinenunterstützung für PushState-URLs

PushState wird derzeit von Google und Bing unterstützt.

Google

Hier ist Matt Cutts, der auf Paul Irishs Frage zu PushState für SEO antwortet:

http://youtu.be/yiAF9VdvRPw

Hier kündigt Google die vollständige JavaScript-Unterstützung für die Spinne an:

http://googlewebmastercentral.blogspot.de/2014/05/understanding-web-pages-better.html

Das Ergebnis ist, dass Google PushState unterstützt und PushState-URLs indiziert.

Siehe auch Google Webmaster-Tools als Googlebot abrufen. Sie werden sehen, dass Ihr JavaScript (einschließlich Angular) ausgeführt wird.

Bing

Hier ist Bings Ankündigung der Unterstützung für hübsche PushState-URLs vom März 2013:

http://blogs.bing.com/webmaster/2013/03/21/search-engine-optimization-best-practices-for-ajax-urls/

Verwende kein HashBangs #!

Hashbang-URLs stellten eine hässliche Notlösung dar, bei der der Entwickler eine vorgerenderte Version der Website an einem bestimmten Ort bereitstellen musste. Sie funktionieren immer noch, aber Sie müssen sie nicht verwenden.

Hashbang-URLs sehen folgendermaßen aus:

domain.com/#!path/to/resource

Dies würde mit einem Metatag wie diesem gepaart werden:

<meta name="fragment" content="!">

Google indiziert sie nicht in diesem Formular, sondern zieht stattdessen eine statische Version der Website aus der _escaped_fragments_-URL und indiziert diese.

PushState-URLs sehen aus wie gewöhnliche URLs:

domain.com/path/to/resource

Der Unterschied besteht darin, dass Angular die Änderungen an document.location in JavaScript abfängt.

Wenn Sie PushState-URLs verwenden möchten (und wahrscheinlich auch), entfernen Sie alle alten Hash-URLs und Metatags und aktivieren Sie einfach den HTML5-Modus in Ihrem Konfigurationsblock.

Testen Sie Ihre Website

Die Google Webmaster-Tools enthalten jetzt ein Tool, mit dem Sie eine URL als Google abrufen und JavaScript so rendern können, wie Google es rendert.

https://www.google.com/webmasters/tools/googlebot-fetch

Generieren von PushState-URLs in Angular

Um echte URLs in Angular anstatt mit # vorangestellten URLs zu generieren, legen Sie den HTML5-Modus für Ihr $ locationProvider-Objekt fest.

$locationProvider.html5Mode(true);

Serverseite

Da Sie echte URLs verwenden, müssen Sie sicherstellen, dass von Ihrem Server für alle gültigen URLs dieselbe Vorlage (plus einige vorkompositionierte Inhalte) geliefert wird. Wie Sie dies tun, hängt von Ihrer Serverarchitektur ab.

Seitenverzeichnis

Ihre App verwendet möglicherweise ungewöhnliche Navigationsformen, z. B. Hover oder Scroll. Um sicherzustellen, dass Google in der Lage ist, Ihre App zu steuern, würde ich wahrscheinlich vorschlagen, eine Sitemap zu erstellen, eine einfache Liste aller URLs, auf die Ihre App reagiert. Sie können dies am Standardspeicherort (/ sitemap oder /sitemap.xml) platzieren oder Google mithilfe von Webmaster-Tools darüber informieren.

Es ist trotzdem eine gute Idee, eine Sitemap zu haben.

Browser-Unterstützung

Pushstate funktioniert in IE10. In älteren Browsern greift Angular automatisch auf URLs im Hash-Stil zurück

Eine Demo-Seite

Der folgende Inhalt wird unter Verwendung einer Pushstate-URL mit Vorkomposition gerendert:

http://html5.gingerhost.com/london

Wie zu überprüfen ist, wird der Inhalt unter dieser Link indexiert und in Google angezeigt.

Bereitstellen von 404- und 301-Header-Statuscodes

Da die Suchmaschine bei jeder Anfrage auf Ihren Server zugreift, können Sie Header-Statuscodes von Ihrem Server ausliefern und von Google erwarten, dass sie angezeigt werden.

470
superluminary

Kommen wir zu AngularJS und SEO

Google, Yahoo, Bing und andere Suchmaschinen durchsuchen das Web auf herkömmliche Weise mit herkömmlichen Crawlern. Sie führen Roboter aus, die den HTML-Code auf Webseiten crawlen und dabei Informationen sammeln. Sie halten interessante Wörter und suchen nach anderen Links zu anderen Seiten (diese Links, deren Anzahl und Anzahl spielen bei SEO eine Rolle).

Warum beschäftigen sich Suchmaschinen nicht mit Javascript-Sites?

Die Antwort hat damit zu tun, dass die Suchmaschinenroboter über kopflose Browser arbeiten und in den meisten Fällen keine JavaScript-Rendering-Engine haben, um das Javascript einer Seite zu rendern. Dies funktioniert für die meisten Seiten, da sich die meisten statischen Seiten nicht um das Rendern ihrer Seite mit JavaScript kümmern, da ihr Inhalt bereits verfügbar ist.

Was kann dagegen getan werden?

Glücklicherweise haben die Crawler der größeren Websites damit begonnen, einen Mechanismus zu implementieren, mit dem wir unsere JavaScript-Websites crawlen können, aber es erfordert, dass wir eine Änderung an unserer Website implementieren .

Wenn wir unser hashPrefix in #! anstatt in # ändern, ändern moderne Suchmaschinen die Anforderung, _escaped_fragment_ anstelle von #! zu verwenden. (Im HTML5-Modus, d. H. Wenn wir Links ohne das Hash-Präfix haben, können wir dieselbe Funktion implementieren, indem wir uns den Header User Agent in unserem Backend ansehen.).

Das heißt, anstelle einer Anfrage von einem normalen Browser, die so aussieht:

http://www.ng-newsletter.com/#!/signup/page

Eine Suchmaschine durchsucht die Seite mit:

http://www.ng-newsletter.com/?_escaped_fragment_=/signup/page

Wir können das Hash-Präfix unserer Angular Apps mithilfe einer integrierten Methode aus ngRoute festlegen:

angular.module('myApp', [])
.config(['$location', function($location) {
  $location.hashPrefix('!');
}]);

Und wenn wir html5Mode verwenden, müssen wir dies mit dem Meta-Tag implementieren:

<meta name="fragment" content="!">

Zur Erinnerung, wir können die html5Mode() mit dem $location -Dienst einstellen:

angular.module('myApp', [])
.config(['$location', 
function($location) {
  $location.html5Mode(true);
}]);

Umgang mit der Suchmaschine

Wir haben viele Möglichkeiten zu bestimmen, wie wir mit der tatsächlichen Bereitstellung von Inhalten für Suchmaschinen als statisches HTML umgehen. Wir können ein Backend selbst hosten, wir können einen Service verwenden, um ein Backend für uns zu hosten, wir können einen Proxy verwenden, um den Inhalt zu liefern, usw. Schauen wir uns einige Optionen an:

Selbst gehostet

Wir können einen Service schreiben, der das Crawlen unserer eigenen Site mit einem kopflosen Browser wie Phantom- oder Zombie-Browsern abwickelt. Dabei wird ein Snapshot der Seite mit gerenderten Daten erstellt und als HTML gespeichert. Immer wenn wir die Abfragezeichenfolge ?_escaped_fragment_ in einer Suchanfrage sehen, können wir den statischen HTML-Schnappschuss, den wir von der Seite erstellt haben, anstelle der vorgerenderten Seite nur über JS liefern. Dies erfordert ein Backend, das unsere Seiten mit bedingter Logik in der Mitte liefert. Wir können so etwas wie prerender.io's als Ausgangspunkt verwenden, um dies selbst auszuführen. Natürlich müssen wir uns noch um das Proxying und das Snippet-Handling kümmern, aber es ist ein guter Anfang.

Mit einem kostenpflichtigen Service

Der einfachste und schnellste Weg, um Inhalte in die Suchmaschine zu bekommen, ist die Verwendung eines Dienstes Brombone , seo.js , seo4ajax und prerender.io sind gute Beispiele dafür, mit denen Sie die oben genannten Inhalte rendern können. Dies ist eine gute Option für Zeiten, in denen wir uns nicht mit der Ausführung eines Servers/Proxys befassen möchten. Außerdem ist es normalerweise sehr schnell.

Weitere Informationen zu Angular und SEO haben wir in einem ausführlichen Tutorial unter http://www.ng-newsletter.com/posts/serious-angular-seo.html beschrieben und ausführlicher haben wir es in unserem Buch ng-book: The Complete Book on AngularJS . Schau es dir an unter ng-book.com .

106
auser

Sie sollten sich unbedingt das Tutorial zum Aufbau einer SEO-freundlichen AngularJS-Site im Jahr des MOO-Blogs ansehen. Er führt Sie durch alle Schritte in Angulars Dokumentation. http://www.yearofmoo.com/2012/11/angularjs-and-seo.html

Mit dieser Technik sieht die Suchmaschine den erweiterten HTML-Code anstelle der benutzerdefinierten Tags.

56
Brad Green

Das hat sich drastisch geändert.

http://searchengineland.com/bing-offers-recommendations-for-seo-friendly-ajax-suggests-html5-pushstate-152946

Wenn Sie Folgendes verwenden: $ locationProvider.html5Mode (true); Sie sind bereit.

Keine Rendering-Seiten mehr.

41
user3330270

Die Dinge haben sich ziemlich verändert, seit diese Frage gestellt wurde. Es gibt jetzt Optionen, mit denen Google Ihre AngularJS-Site indizieren kann. Die einfachste Option, die ich gefunden habe, war die Verwendung von http://prerender.io kostenlosem Service, der die crwalable-Seiten für Sie generiert und serviere das den Suchmaschinen. Es wird auf fast allen serverseitigen Webplattformen unterstützt. Ich habe vor kurzem angefangen, sie zu benutzen und die Unterstützung ist auch ausgezeichnet.

Ich habe keine Zugehörigkeit zu ihnen, dies kommt von einem zufriedenen Benutzer.

17
Ketan

Angulars eigene Website bietet Suchmaschinen vereinfachten Inhalt: http://docs.angularjs.org/?_escaped_fragment_=/tutorial/step_09

Angenommen, Ihre Angular App verwendet eine Node.js/Express-gesteuerte JSON-API wie /api/path/to/resource. Möglicherweise können Sie Anforderungen mit ?_escaped_fragment_ an /api/path/to/resource.html umleiten und Inhaltsaushandlung verwenden, um eine HTML-Vorlage des Inhalts zu rendern, anstatt die JSON-Daten zurückzugeben.

Das einzige ist, dass Ihre Angular Routen 1: 1 mit Ihrer REST API übereinstimmen müssen.

EDIT: Mir ist klar, dass dies das Potenzial hat, Ihre REST API wirklich zu verschmutzen, und ich rate nicht dazu Dies außerhalb sehr einfacher Anwendungsfälle, bei denen es sich möglicherweise um eine natürliche Anpassung handelt.

Stattdessen können Sie für Ihre roboterfreundlichen Inhalte ganz andere Routen und Steuerungen verwenden. Aber dann duplizieren Sie alle Ihre AngularJS-Routen und -Controller in Node/Express.

Ich habe mich entschlossen, Schnappschüsse mit einem kopflosen Browser zu erstellen, obwohl ich der Meinung bin, dass dies ein wenig weniger als ideal ist.

9
Kevin C.
8
pixparker

Ab sofort hat Google den Crawling-Vorschlag für AJAX geändert.

Die Zeiten haben sich geändert. Solange Sie Googlebot nicht daran hindern, Ihre JavaScript- oder CSS-Dateien zu crawlen, können wir Ihre Webseiten im Allgemeinen wie moderne Browser rendern und verstehen.

tl; dr: [Google] empfiehlt nicht mehr den AJAX Crawling-Vorschlag [Google] aus dem Jahr 2009.

7
Thor

Die crawlbare Ajax-Spezifikation von Google, auf die in den anderen Antworten hier verwiesen wird, ist im Grunde die Antwort.

Wenn Sie daran interessiert sind, wie andere Suchmaschinen und soziale Bots mit den gleichen Problemen umgehen, habe ich den Stand der Technik hier aufgeschrieben: http://blog.ajaxsnapshots.com/2013/11/googles-crawlable-ajax -specification.html

Ich arbeite für ein https://ajaxsnapshots.com , ein Unternehmen, das die Crawlable Ajax Spec als Service implementiert. Die Informationen in diesem Bericht basieren auf Beobachtungen aus unseren Protokollen.

6
Robert AJS

Ich habe eine elegante Lösung gefunden, die die meisten Ihrer Basen abdecken würde. Ich schrieb anfangs darüber hier und beantwortete eine andere ähnliche StackOverflow-Frage hier , die darauf verweist.

Zu Ihrer Information enthält diese Lösung auch fest codierte Fallback-Tags, falls Javascript nicht vom Crawler erfasst wird. Ich habe es nicht explizit umrissen, aber es ist erwähnenswert, dass Sie den HTML5-Modus für eine ordnungsgemäße URL-Unterstützung aktivieren sollten.

Beachten Sie auch, dass dies nicht die vollständigen Dateien sind, sondern nur die wichtigen Teile der relevanten Dateien. Wenn Sie Hilfe beim Erstellen des Kesselschilds für Richtlinien, Dienstleistungen usw. benötigen, das Sie an anderer Stelle finden. Wie auch immer, hier geht ...

app.js

Hier stellen Sie die benutzerdefinierten Metadaten für jede Ihrer Routen (Titel, Beschreibung usw.) bereit.

$routeProvider
   .when('/', {
       templateUrl: 'views/homepage.html',
       controller: 'HomepageCtrl',
       metadata: {
           title: 'The Base Page Title',
           description: 'The Base Page Description' }
   })
   .when('/about', {
       templateUrl: 'views/about.html',
       controller: 'AboutCtrl',
       metadata: {
           title: 'The About Page Title',
           description: 'The About Page Description' }
   })

metadata-service.js (service)

Legt die benutzerdefinierten Metadatenoptionen fest oder verwendet die Standardeinstellungen als Ersatz.

var self = this;

// Set custom options or use provided fallback (default) options
self.loadMetadata = function(metadata) {
  self.title = document.title = metadata.title || 'Fallback Title';
  self.description = metadata.description || 'Fallback Description';
  self.url = metadata.url || $location.absUrl();
  self.image = metadata.image || 'fallbackimage.jpg';
  self.ogpType = metadata.ogpType || 'website';
  self.twitterCard = metadata.twitterCard || 'summary_large_image';
  self.twitterSite = metadata.twitterSite || '@fallback_handle';
};

// Route change handler, sets the route's defined metadata
$rootScope.$on('$routeChangeSuccess', function (event, newRoute) {
  self.loadMetadata(newRoute.metadata);
});

metaproperty.js (Direktive)

Packt die Metadatendienstergebnisse für die Ansicht.

return {
  restrict: 'A',
  scope: {
    metaproperty: '@'
  },
  link: function postLink(scope, element, attrs) {
    scope.default = element.attr('content');
    scope.metadata = metadataService;

    // Watch for metadata changes and set content
    scope.$watch('metadata', function (newVal, oldVal) {
      setContent(newVal);
    }, true);

    // Set the content attribute with new metadataService value or back to the default
    function setContent(metadata) {
      var content = metadata[scope.metaproperty] || scope.default;
      element.attr('content', content);
    }

    setContent(scope.metadata);
  }
};

index.html

Komplett mit den zuvor erwähnten fest codierten Fallback-Tags für Crawler, die kein Javascript aufnehmen können.

<head>
  <title>Fallback Title</title>
  <meta name="description" metaproperty="description" content="Fallback Description">

  <!-- Open Graph Protocol Tags -->
  <meta property="og:url" content="fallbackurl.com" metaproperty="url">
  <meta property="og:title" content="Fallback Title" metaproperty="title">
  <meta property="og:description" content="Fallback Description" metaproperty="description">
  <meta property="og:type" content="website" metaproperty="ogpType">
  <meta property="og:image" content="fallbackimage.jpg" metaproperty="image">

  <!-- Twitter Card Tags -->
  <meta name="Twitter:card" content="summary_large_image" metaproperty="twitterCard">
  <meta name="Twitter:title" content="Fallback Title" metaproperty="title">
  <meta name="Twitter:description" content="Fallback Description" metaproperty="description">
  <meta name="Twitter:site" content="@fallback_handle" metaproperty="twitterSite">
  <meta name="Twitter:image:src" content="fallbackimage.jpg" metaproperty="image">
</head>

Dies sollte in den meisten Anwendungsfällen von Suchmaschinen erheblich helfen. Wenn Sie ein vollständig dynamisches Rendering für Crawler in sozialen Netzwerken wünschen (die Javascript nicht unterstützen), müssen Sie dennoch einen der in einigen anderen Antworten genannten Vorrendering-Dienste verwenden.

Hoffe das hilft!

4
Andrew

Mit Angular Universal können Sie Landing Pages für die App erstellen, die wie die vollständige App aussehen, und anschließend Ihre Angular App dahinter laden.
Angular Universal generiert reines HTML, dh Seiten ohne Javascript auf der Serverseite, und stellt sie den Benutzern ohne Verzögerung zur Verfügung. So können Sie mit jedem Crawler, Bot und Benutzer (der bereits eine niedrige CPU- und Netzwerkgeschwindigkeit hat) umgehen. Anschließend können Sie sie über Links/Schaltflächen zu Ihrer aktuellen angular App umleiten, die bereits dahinter geladen ist. Diese Lösung wird von der offiziellen Website empfohlen. - Weitere Informationen zu SEO und Angular Universal -

2
erginduran

Verwenden Sie so etwas wie PreRender. Es erstellt statische Seiten Ihrer Website, damit Suchmaschinen sie indizieren können.

Hier erfahren Sie, für welche Plattformen es verfügbar ist: https://prerender.io/documentation/install-middleware#asp-net

2
NicoJuicy

Crawler (oder Bots) dienen zum Crawlen von HTML-Inhalten von Webseiten. Aufgrund von AJAX Vorgängen für das asynchrone Abrufen von Daten wurde dies jedoch zu einem Problem, da das Rendern von Seiten und das Anzeigen von dynamischem Inhalt einige Zeit in Anspruch nimmt. In ähnlicher Weise verwendet AngularJS auch ein asynchrones Modell, was für Google-Crawler ein Problem darstellt.

Einige Entwickler erstellen einfache HTML-Seiten mit echten Daten und liefern diese Seiten zum Zeitpunkt des Crawls von der Serverseite aus. Wir können die gleichen Seiten mit PhantomJS auf der Serverseite rendern, die _escaped_fragment_ enthält (da Google in den URLs unserer Website nach #! sucht und dann alles nach #! hinzufügt) _escaped_fragment_ Abfrageparameter). Für weitere Informationen lesen Sie bitte diese Blog .

1
Rubi saini

Die Crawler benötigen keine reichhaltig ausgestattete, hübsch gestaltete Benutzeroberfläche, sie möchten nur den Inhalt sehen, daher müssen Sie ihnen keinen Schnappschuss einer Seite geben, die für Menschen erstellt wurde.

Meine Lösung: Gib dem Crawler, was der Crawler will:

Sie müssen sich überlegen, was der Crawler will, und ihm nur das geben.

TIPP Leg dich nicht mit dem Rücken an. Fügen Sie einfach eine kleine serverseitige Frontansicht mit derselben API hinzu

0
pykiss