web-dev-qa-db-fra.com

Comment les moteurs de recherche traitent-ils les applications AngularJS?

Je vois deux problèmes avec l'application AngularJS concernant les moteurs de recherche et le référencement:

1) Que se passe-t-il avec les balises personnalisées? Les moteurs de recherche ignorent-ils tout le contenu de ces balises? je suppose que j'ai

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

<h1> serait-il indexé alors qu'il se trouvait dans des balises personnalisées?


2) Existe-t-il un moyen d’éviter que les moteurs de recherche à indexation {{}} ne se lient littéralement? c'est à dire.

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

Je sais que je pourrais faire quelque chose comme

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

mais si je veux laisser le robot "voir" le titre? Le rendu côté serveur est-il la seule solution?

695
luisfarzati

Mise à jour de mai 2014

Google crawlers exécute maintenant le javascript - vous pouvez utiliser le Google Webmaster Tools pour mieux comprendre le rendu de vos sites par Google.

Réponse originale
Si vous souhaitez optimiser votre application pour les moteurs de recherche, vous ne pouvez malheureusement pas fournir de version pré-affichée au robot. Vous pouvez en savoir plus sur les recommandations de Google relatives aux sites ajax et javascript-heavy here .

Si cela est une option, je vous recommande de lire cet article sur la procédure de référencement pour Angular avec un rendu côté serveur.

Je ne sais pas ce que le robot fait lorsqu'il rencontre des balises personnalisées.

404
joakimbl

Utiliser PushState et Precomposition

La manière actuelle (2015) de procéder consiste à utiliser la méthode JavaScript pushState.

PushState modifie l'URL dans la barre de navigation supérieure sans recharger la page. Disons que vous avez une page contenant des onglets. Les onglets masquent et affichent le contenu, et le contenu est inséré dynamiquement, soit à l'aide de AJAX, soit simplement en définissant display: none et display: block to hide et afficher le contenu correct.

Lorsque vous cliquez sur les onglets, utilisez pushState pour mettre à jour l'URL dans la barre d'adresse. Lorsque la page est rendue, utilisez la valeur dans la barre d'adresse pour déterminer quel onglet afficher. Angular routage le fera automatiquement pour vous.

Précomposition

Il existe deux manières de frapper une application de page unique PushState (SPA)

  1. Via PushState, où l'utilisateur clique sur un lien PushState et dont le contenu est AJAXed in.
  2. En tapant directement l'URL.

Le coup initial sur le site impliquera de frapper directement l'URL. Les hits suivants seront simplement AJAX dans le contenu lorsque PushState met à jour l'URL.

Les robots d'exploration collectent les liens d'une page, puis les ajoutent à une file d'attente pour un traitement ultérieur. Cela signifie que pour un robot d'exploration, chaque coup sur le serveur est un coup direct, ils ne naviguent pas via Pushstate.

La précomposition regroupe la charge initiale dans la première réponse du serveur, éventuellement sous forme d'objet JSON. Cela permet au moteur de recherche d'afficher la page sans exécuter l'appel AJAX.

Certaines preuves suggèrent que Google pourrait ne pas exécuter les requêtes AJAX. Plus sur ceci ici:

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

Les moteurs de recherche peuvent lire et exécuter du JavaScript

Google est capable d'analyser JavaScript depuis quelque temps déjà, c'est pourquoi ils ont initialement développé Chrome, pour agir comme un navigateur sans tête complet pour Google Spider. Si un lien a un attribut href valide, la nouvelle URL peut être indexée. Il n'y a plus rien à faire.

Si un clic sur un lien déclenche en outre un appel PushState, l'utilisateur peut naviguer sur le site via PushState.

Prise en charge des moteurs de recherche pour les URL PushState

PushState est actuellement pris en charge par Google et Bing.

Google

Matt Cutts répond à la question de Paul Irish sur PushState for SEO:

http://youtu.be/yiAF9VdvRPw

Voici Google annonçant la prise en charge complète de JavaScript par l'araignée:

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

Le résultat est que Google prend en charge PushState et indexera les URL PushState.

Voir aussi l'extraction de Google Webmaster Tools en tant que Googlebot. Vous verrez que votre JavaScript (y compris angulaire) est exécuté.

Bing

Voici l'annonce par Bing de la prise en charge de jolies URL PushState datée de mars 2013:

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

N'utilisez pas HashBangs #!

Les URL hachbang constituaient un palliatif moche qui obligeait le développeur à fournir une version pré-affichée du site à un emplacement spécial. Ils fonctionnent toujours, mais vous n'avez pas besoin de les utiliser.

Les URL Hashbang ressemblent à ceci:

domain.com/#!path/to/resource

Cela serait associé à une métabalise comme ceci:

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

Google ne les indexera pas sous cette forme, mais extraira une version statique du site à partir de l'URL _escaped_fragments_ et l'indexera.

Les URL Pushstate ressemblent à n'importe quelle URL ordinaire:

domain.com/path/to/resource

La différence est que Angular les gère pour vous en interceptant la modification apportée à document.location qui la traite en JavaScript.

Si vous souhaitez utiliser les URL PushState (et vous le faites probablement), supprimez toutes les anciennes URL et métabalises de style de hachage et activez simplement le mode HTML5 dans votre bloc de configuration.

Tester votre site

Les outils pour les webmasters de Google contiennent maintenant un outil qui vous permettra de récupérer une URL en tant que google et de rendre JavaScript en tant que Google.

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

Génération d'URL PushState en angulaire

Pour générer des URL réelles en caractères angulaires plutôt que # avec préfixes, définissez le mode HTML5 sur votre objet $ locationProvider.

$locationProvider.html5Mode(true);

Du côté serveur

Étant donné que vous utilisez de véritables URL, vous devez vous assurer que le même modèle (ainsi que du contenu précomposé) est envoyé par votre serveur pour toutes les URL valides. La procédure à suivre dépend de l’architecture de votre serveur.

Plan du site

Votre application peut utiliser des formes de navigation inhabituelles, telles que le survol ou le défilement. Pour que Google puisse piloter votre application, je suggérerais probablement de créer un plan du site, une liste simple de toutes les URL auxquelles votre application répond. Vous pouvez le placer à l'emplacement par défaut (/ sitemap ou /sitemap.xml) ou en informer Google à l'aide des outils pour les webmasters.

C'est une bonne idée d'avoir un sitemap quand même.

Support du navigateur

Pushstate fonctionne dans IE10. Dans les navigateurs plus anciens, Angular utilisera automatiquement les URL de style de hachage.

Une page de démonstration

Le contenu suivant est rendu à l'aide d'une URL Pushstate avec précomposition:

http://html5.gingerhost.com/london

Comme on peut le vérifier, à ce lien , le contenu est indexé et apparaît dans Google.

Traitement des codes d'état d'en-tête 404 et 301

Le moteur de recherche sollicitant toujours votre serveur pour chaque requête, vous pouvez lui transmettre les codes d’état d’en-tête et attendre que Google les voie.

470
superluminary

Soyons définitifs sur AngularJS et le référencement

Google, Yahoo, Bing et d'autres moteurs de recherche explorent le Web de manière traditionnelle à l'aide de robots d'exploration traditionnels. Ils exécutent des robots qui analysent le code HTML dans les pages Web et collectent des informations en cours de route. Ils gardent des mots intéressants et recherchent d'autres liens vers d'autres pages (ces liens, leur nombre et leur nombre entrent en jeu avec le référencement).

Alors, pourquoi les moteurs de recherche ne traitent-ils pas avec des sites javascript?

La réponse tient au fait que les robots des moteurs de recherche fonctionnent avec des navigateurs sans tête et qu’ils n’ont pas un moteur de rendu javascript pour restituer le javascript d'une page. Cela fonctionne pour la plupart des pages, car la plupart des pages statiques ne se soucient pas du rendu JavaScript de leur page, car leur contenu est déjà disponible.

Que peut-on faire à ce sujet?

Heureusement, les crawlers des plus grands sites ont commencé à mettre en place un mécanisme nous permettant de rendre nos sites JavaScript explorables, mais il nous oblige à mettre en place une modification de notre site .

Si nous modifions notre hashPrefix en #! au lieu de simplement #, les moteurs de recherche modernes modifieront la demande en utilisant _escaped_fragment_ au lieu de #!. (Avec le mode HTML5, c’est-à-dire où nous avons des liens sans le préfixe de hachage, nous pouvons implémenter cette même fonctionnalité en consultant l’en-tête User Agent dans notre backend).

C'est-à-dire, au lieu d'une requête d'un navigateur normal qui ressemble à ceci:

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

Un moteur de recherche effectuera une recherche sur la page avec:

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

Nous pouvons définir le préfixe de hachage de nos applications Angular à l'aide d'une méthode intégrée de ngRoute:

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

Et, si nous utilisons html5Mode, nous devrons l'implémenter en utilisant la balise META:

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

Pour rappel, nous pouvons paramétrer la html5Mode() avec le service $location:

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

Manipulation du moteur de recherche

Nous avons beaucoup d'occasions de déterminer comment nous allons gérer la fourniture de contenu aux moteurs de recherche sous forme de code HTML statique. Nous pouvons héberger nous-mêmes un serveur, nous pouvons utiliser un service pour héberger un serveur pour nous, nous pouvons utiliser un proxy pour fournir le contenu, etc. Voyons quelques options:

Auto-hébergé

Nous pouvons écrire un service pour gérer l’exploration de notre propre site en utilisant un navigateur sans navigateur, comme phantomjs ou zombiejs, en prenant un instantané de la page avec les données rendues et en le stockant au format HTML. Chaque fois que nous voyons la chaîne de requête ?_escaped_fragment_ dans une requête de recherche, nous pouvons livrer le cliché HTML statique que nous avons pris de la page au lieu de la page pré-rendue par le biais de JS uniquement. Cela nécessite que nous ayons un backend fournissant nos pages avec une logique conditionnelle au milieu. Nous pouvons utiliser quelque chose comme --- le backend de prerender.io comme point de départ pour le faire nous-mêmes. Bien sûr, nous devons encore gérer le proxy et le traitement des extraits, mais c'est un bon début.

Avec un service payant

Le moyen le plus simple et le plus rapide d’obtenir du contenu dans le moteur de recherche est d’utiliser un service Brombone , seo.js , seo4ajax , et prerender.io sont de bons exemples de ceux-ci qui hébergeront le rendu du contenu ci-dessus pour vous. C'est une bonne option pour les moments où nous ne voulons pas gérer un serveur/proxy. En outre, c'est généralement très rapide.

Pour plus d'informations sur Angular et le référencement, nous avons rédigé un didacticiel complet à l'adresse suivante: http://www.ng-newsletter.com/posts/serious-angular-seo.html et nous l'avons détaillé davantage dans notre livre ng-book: Le livre complet sur AngularJS . Vérifiez-le à ng-book.com .

106
auser

Vous devriez vraiment consulter le tutoriel sur la construction d'un site AngularJS optimisé pour le référencement sur l'année du blog moo. Il vous guide à travers toutes les étapes décrites dans la documentation d'Angular. http://www.yearofmoo.com/2012/11/angularjs-and-seo.html

En utilisant cette technique, le moteur de recherche voit le code HTML développé au lieu des balises personnalisées.

56
Brad Green

Cela a radicalement changé.

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

Si vous utilisez: $ locationProvider.html5Mode (true); tu es prêt.

Pas plus de pages de rendu.

41
user3330270

Les choses ont bien changé depuis que cette question a été posée. Il existe désormais des options permettant à Google d'indexer votre site AngularJS. L'option la plus simple que j'ai trouvée était d'utiliser http://prerender.io un service gratuit qui générera les pages crwalable pour vous. et servir cela aux moteurs de recherche. Il est pris en charge sur presque toutes les plates-formes Web côté serveur. J'ai récemment commencé à les utiliser et le support est excellent également.

Je n'ai aucune affiliation avec eux, cela provient d'un utilisateur heureux.

17
Ketan

Le propre site Web d'Angular sert un contenu simplifié aux moteurs de recherche: http://docs.angularjs.org/?_escaped_fragment_=/tutorial/step_09

Supposons que votre application Angular consomme une API JSON Node.js/Express, telle que /api/path/to/resource. Peut-être pourriez-vous rediriger toutes les demandes avec ?_escaped_fragment_ vers /api/path/to/resource.html et utiliser négociation de conten pour restituer un modèle HTML du contenu, plutôt que de renvoyer les données JSON.

La seule chose à faire est que vos routes Angular devraient correspondre à 1: 1 avec votre API REST.

EDIT: Je réalise que cela a le potentiel de brouiller votre REST api et je ne le recommande pas. le faire en dehors de cas d'utilisation très simples où cela pourrait être un ajustement naturel.

Au lieu de cela, vous pouvez utiliser un ensemble entièrement différent de routes et de contrôleurs pour votre contenu convivial pour les robots. Mais ensuite, vous dupliquez toutes vos routes et vos contrôleurs AngularJS dans Node/Express.

J'ai opté pour la génération d'instantanés avec un navigateur sans navigateur, même si cela me semble un peu moins qu'idéal.

9
Kevin C.
8
pixparker

À partir de maintenant, Google a modifié sa proposition d'exploration AJAX.

Les temps ont changé. Aujourd'hui, tant que vous n'empêchez pas Googlebot d'explorer vos fichiers JavaScript ou CSS, nous sommes généralement en mesure de générer et de comprendre vos pages Web, à la manière des navigateurs modernes.

tl; dr: [Google] ne recommande plus la proposition d'exploration AJAX _ faite par Google en 2009.

7
Thor

La spécification Ajax Specable de Google, comme indiqué dans les autres réponses ici, est fondamentalement la solution.

Si vous êtes intéressé par la façon dont d'autres moteurs de recherche et bots sociaux traitent les mêmes problèmes, j'ai rédigé ici l'état de l'art: http://blog.ajaxsnapshots.com/2013/11/googles-crawlable-ajax -specification.html

Je travaille pour https://ajaxsnapshots.com , une société qui implémente Crawlax Ajax Spec en tant que service - les informations contenues dans ce rapport sont basées sur les observations de nos journaux.

6
Robert AJS

J'ai trouvé une solution élégante qui couvrirait la plupart de vos bases. J'avais d'abord écrit à ce sujet ici et répondu à une autre question similaire à StackOverflow ici qui y fait référence.

Pour votre information, cette solution inclut également des balises de secours codées en dur au cas où Javascript ne serait pas capté par le robot. Je ne l'ai pas explicitement décrit, mais il convient de mentionner que vous devriez activer le mode HTML5 pour une prise en charge correcte des URL.

Notez également que ces fichiers ne sont pas complets, mais seulement les parties importantes de ceux qui sont pertinents. Si vous avez besoin d’aide pour rédiger le passe-partout pour des directives, des services, etc., disponibles ailleurs. Quoi qu'il en soit, voici ...

app.js

C'est ici que vous fournissez les métadonnées personnalisées pour chacun de vos itinéraires (titre, description, etc.).

$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)

Définit les options de métadonnées personnalisées ou utilise les valeurs par défaut comme solutions de secours.

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 (directive)

Met en paquets les résultats du service de métadonnées pour la vue.

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

Complétez les balises de secours codées en dur mentionnées précédemment, pour les robots qui ne peuvent pas lire de code Javascript.

<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>

Cela devrait aider considérablement avec la plupart des cas d'utilisation de moteur de recherche. Si vous souhaitez un rendu totalement dynamique pour les robots d'exploration de réseaux sociaux (qui sont douteux avec le support Javascript), vous devrez toujours utiliser l'un des services de pré-rendu mentionné dans certaines des autres réponses.

J'espère que cela t'aides!

4
Andrew

Avec Angular Universal, vous pouvez générer des pages de renvoi pour l'application qui ressemblent à l'application complète, puis charger votre application Angular derrière celle-ci.
Angular Universal génère du code HTML pur, c'est-à-dire des pages sans javascript côté serveur, et les diffuse aux utilisateurs sans délai. Ainsi, vous pouvez gérer tous les robots, robots et utilisateurs (qui ont déjà un processeur et une vitesse de réseau faibles). Ensuite, vous pouvez les rediriger par des liens/boutons vers votre application angular qui a déjà été chargée. Cette solution est recommandée par le site officiel. - Plus d'infos sur le référencement et Angular Universel -

2
erginduran

Utilisez quelque chose comme PreRender, cela crée des pages statiques de votre site afin que les moteurs de recherche puissent l’indexer.

Ici vous pouvez trouver pour quelles plateformes il est disponible: https://prerender.io/documentation/install-middleware#asp-net

2
NicoJuicy

Les robots d'exploration (ou bots) sont conçus pour analyser le contenu HTML des pages Web, mais en raison des opérations AJAX pour l'extraction de données asynchrone, cela est devenu un problème car il fallait parfois du temps pour afficher une page et afficher du contenu dynamique. De même, AngularJS utilise également un modèle asynchrone, ce qui crée un problème pour les robots d'exploration de Google.

Certains développeurs créent des pages HTML de base avec des données réelles et les servent du côté serveur au moment de l’exploration. Nous pouvons restituer les mêmes pages avec PhantomJS du côté du service qui contient _escaped_fragment_ (car Google recherche #! dans les URL de notre site, puis prend tout ce qui suit le #! et l'ajoute _escaped_fragment_ paramètre de requête). Pour plus de détails, lisez ceci blog .

1
Rubi saini

Les robots d'exploration n'ont pas besoin d'une interface graphique sophistiquée, ils veulent seulement voir le conten, vous n'avez donc pas besoin de leur donner un instantané d'une page conçue pour les humains.

Ma solution: to donner au robot ce que le robot veut:

Vous devez penser à ce que veut le robot d'exploration et ne lui donner que cela.

CONSEIL ne plaisante pas avec le dos. Ajoutez simplement une petite vue de face côté serveur en utilisant la même API

0
pykiss