¿Cómo tratan los motores de búsqueda las aplicaciones AngularJS?
Veo dos problemas con la aplicación AngularJS con respecto a los motores de búsqueda y SEO:
1) ¿Qué pasa con las etiquetas personalizadas? ¿Los motores de búsqueda ignoran todo el contenido de esas etiquetas? es decir, supongo que tengo
<custom>
<h1>Hey, this title is important</h1>
</custom>
¿ Se <h1>
indexaría a pesar de estar dentro de etiquetas personalizadas?
2) ¿Hay alguna manera de evitar que los motores de búsqueda indexen {{}} enlaces literalmente? es decir
<h2>{{title}}</h2>
Sé que podría hacer algo como
<h2 ng-bind="title"></h2>
pero ¿qué pasa si quiero dejar que el rastreador "vea" el título? ¿Es la renderización del lado del servidor la única solución?
(2022) Utilice la representación del lado del servidor si es posible y genere URL con Pushstate
Google puede ejecutar y ejecutará JavaScript ahora, por lo que es muy posible crear un sitio utilizando únicamente JavaScript siempre que cree una estructura de URL sensata. Sin embargo, la velocidad de la página se ha convertido en un factor de clasificación cada vez más importante y, por lo general, las páginas creadas en el lado del cliente tienen un rendimiento deficiente en el procesamiento inicial.
La representación del lado del servidor (SSR) puede ayudar al permitir que sus páginas se generen previamente en el servidor. Su html contiene el div que se usará como raíz de la página, pero este no es un div vacío, contiene el html que JavaScript habría generado si se le hubiera permitido ejecutarse.
El cliente descarga el HTML y lo renderiza dando una carga inicial muy rápida, luego ejecuta JavaScript reemplazando el contenido del div raíz con contenido generado en un proceso conocido como hidratación.
Muchos marcos más nuevos vienen con SSR integrado, en particular NextJS.
(2015) Utilice PushState y precomposición
La forma actual (2015) de hacer esto es utilizar el método pushState de JavaScript.
PushState cambia la URL en la barra superior del navegador sin recargar la página. Digamos que tiene una página que contiene pestañas. Las pestañas ocultan y muestran contenido, y el contenido se inserta dinámicamente, ya sea usando AJAX o simplemente configurando display:none y display:block para ocultar y mostrar el contenido de la pestaña correcta.
Cuando se hace clic en las pestañas, use pushState para actualizar la URL en la barra de direcciones. Cuando se represente la página, use el valor en la barra de direcciones para determinar qué pestaña mostrar. El enrutamiento angular hará esto automáticamente.
Precomposición
Hay dos formas de acceder a una aplicación de página única (SPA) PushState
- A través de PushState, donde el usuario hace clic en un enlace PushState y el contenido se introduce en AJAX.
- Pulsando la URL directamente.
El acceso inicial al sitio implicará acceder directamente a la URL. Las visitas posteriores simplemente tendrán contenido AJAX a medida que PushState actualice la URL.
Los rastreadores recopilan enlaces de una página y luego los agregan a una cola para su posterior procesamiento. Esto significa que para un rastreador, cada acceso al servidor es un acceso directo, no navega a través de Pushstate.
La precomposición agrupa la carga útil inicial en la primera respuesta del servidor, posiblemente como un objeto JSON. Esto permite que el motor de búsqueda muestre la página sin ejecutar la llamada AJAX.
Existe alguna evidencia que sugiere que es posible que Google no ejecute solicitudes AJAX. Más sobre esto aquí:
https://web.archive.org/web/20160318211223/http://www.analog-ni.co/precomposing-a-spa-may-become-the-holy-grail-to-seo
Los motores de búsqueda pueden leer y ejecutar JavaScript
Google ha podido analizar JavaScript desde hace algún tiempo, es por eso que desarrollaron originalmente Chrome, para que actúe como un navegador sin cabeza con todas las funciones para la araña de Google. Si un enlace tiene un atributo href válido, la nueva URL se puede indexar. No hay nada más que hacer.
Si al hacer clic en un enlace se activa además una llamada pushState, el usuario puede navegar por el sitio a través de PushState.
Soporte de motor de búsqueda para URL PushState
Actualmente, PushState cuenta con el respaldo de Google y Bing.
Aquí está Matt Cutts respondiendo a la pregunta de Paul Irish sobre PushState para SEO:
http://youtu.be/yiAF9VdvRPw
Aquí está Google anunciando soporte completo de JavaScript para la araña:
http://googlewebmastercentral.blogspot.de/2014/05/understanding-web-pages-better.html
El resultado es que Google admite PushState e indexará las URL de PushState.
Consulte también la búsqueda de herramientas para webmasters de Google como Googlebot. Verá que se ejecuta su JavaScript (incluido Angular).
Bing
Aquí está el anuncio de Bing de soporte para bonitas URL PushState con fecha de marzo de 2013:
http://blogs.bing.com/webmaster/2013/03/21/search-engine-optimization-best-practices-for-ajax-urls/
¡No uses HashBangs #!
Las URL de Hashbang eran un feo recurso provisional que requería que el desarrollador proporcionara una versión renderizada previamente del sitio en una ubicación especial. Todavía funcionan, pero no es necesario utilizarlos.
Las URL de Hashbang se ven así:
domain.example/#!path/to/resource
Esto se combinaría con una metaetiqueta como esta:
<meta name="fragment" content="!">
Google no los indexará de esta forma, sino que extraerá una versión estática del sitio de la URL escaped_fragments y la indexará.
Las URL Pushstate se parecen a cualquier URL normal:
domain.example/path/to/resource
La diferencia es que Angular los maneja por usted interceptando el cambio en document.location que lo maneja en JavaScript.
Si desea utilizar URL PushState (y probablemente lo desee), elimine todas las URL y metaetiquetas de estilo hash antiguo y simplemente habilite el modo HTML5 en su bloque de configuración.
Probando su sitio
Las Herramientas para webmasters de Google ahora contienen una herramienta que le permitirá buscar una URL como Google y representar JavaScript como lo hace Google.
https://www.google.com/webmasters/tools/googlebot-fetch
Generando URL PushState en Angular
Para generar URL reales en Angular, en lugar de las con prefijo #, configure el modo HTML5 en su objeto $locationProvider.
$locationProvider.html5Mode(true);
Lado del servidor
Dado que está utilizando URL reales, deberá asegurarse de que su servidor envíe la misma plantilla (más algo de contenido precompuesto) para todas las URL válidas. La forma de hacer esto variará según la arquitectura de su servidor.
Mapa del sitio
Su aplicación puede utilizar formas inusuales de navegación, por ejemplo, desplazarse o desplazarse. Para garantizar que Google pueda gestionar su aplicación, probablemente sugeriría crear un mapa del sitio, una lista simple de todas las URL a las que responde su aplicación. Puede colocarlo en la ubicación predeterminada (/sitemap o /sitemap.xml) o informarle a Google mediante las herramientas para webmasters.
De todos modos, es una buena idea tener un mapa del sitio.
Soporte del navegador
Pushstate funciona en IE10. En navegadores más antiguos, Angular recurrirá automáticamente a las URL de estilo hash
Una página de demostración
El siguiente contenido se representa utilizando una URL pushstate con precomposición:
http://html5.gingerhost.com/londres
Como se puede comprobar, en este enlace , el contenido está indexado y está apareciendo en Google.
Sirviendo códigos de estado de encabezado 404 y 301
Debido a que el motor de búsqueda siempre llegará a su servidor para cada solicitud, puede enviar códigos de estado de encabezado desde su servidor y esperar que Google los vea.
Actualización mayo 2014
Los rastreadores de Google ahora ejecutan JavaScript ; puede utilizar las Herramientas para webmasters de Google para comprender mejor cómo Google representa sus sitios.
Respuesta original
Si desea optimizar su aplicación para los motores de búsqueda, lamentablemente no hay forma de ofrecer una versión renderizada previamente al rastreador. Puede leer más sobre las recomendaciones de Google para sitios con uso intensivo de ajax y javascript aquí .
Si esta es una opción, recomiendo leer este artículo sobre cómo hacer SEO para Angular con renderizado del lado del servidor.
No estoy seguro de qué hace el rastreador cuando encuentra etiquetas personalizadas.
Seamos definitivos sobre AngularJS y SEO
Google, Yahoo, Bing y otros motores de búsqueda rastrean la web de forma tradicional utilizando rastreadores tradicionales. Ejecutan robots que rastrean el HTML de las páginas web y recopilan información a lo largo del camino. Guardan palabras interesantes y buscan otros enlaces a otras páginas (estos enlaces, la cantidad de ellos y el número de ellos entran en juego con el SEO).
Entonces, ¿por qué los motores de búsqueda no tratan con sitios javascript?
La respuesta tiene que ver con el hecho de que los robots de los motores de búsqueda funcionan a través de navegadores sin cabeza y, en la mayoría de los casos, no tienen un motor de renderizado de JavaScript para representar el javascript de una página. Esto funciona para la mayoría de las páginas, ya que a la mayoría de las páginas estáticas no les importa que JavaScript represente su página, ya que su contenido ya está disponible.
¿Qué se puede hacer al respecto?
Afortunadamente, los rastreadores de los sitios más grandes han comenzado a implementar un mecanismo que nos permite hacer que nuestros sitios JavaScript sean rastreables, pero requiere que implementemos un cambio en nuestro sitio .
Si cambiamos nuestro hashPrefix
a ser #!
en lugar de simplemente #
, los motores de búsqueda modernos cambiarán la solicitud para usar _escaped_fragment_
en lugar de #!
. (Con el modo HTML5, es decir, cuando tenemos enlaces sin el prefijo hash, podemos implementar esta misma característica mirando el User Agent
encabezado en nuestro backend).
Es decir, en lugar de una solicitud de un navegador normal que se ve así:
http://www.ng-newsletter.com/#!/signup/page
Un motor de búsqueda buscará en la página con:
http://www.ng-newsletter.com/?_escaped_fragment_=/signup/page
Podemos configurar el prefijo hash de nuestras aplicaciones Angular usando un método integrado de ngRoute
:
angular.module('myApp', [])
.config(['$location', function($location) {
$location.hashPrefix('!');
}]);
Y, si usamos html5Mode
, necesitaremos implementar esto usando la metaetiqueta:
<meta name="fragment" content="!">
Recordatorio, podemos configurar html5Mode()
con el $location
servicio:
angular.module('myApp', [])
.config(['$location',
function($location) {
$location.html5Mode(true);
}]);
Manejo del motor de búsqueda
Tenemos muchas oportunidades para determinar cómo abordaremos la entrega de contenido a los motores de búsqueda como HTML estático. Podemos alojar un backend nosotros mismos, podemos usar un servicio para alojar un backend, podemos usar un proxy para entregar el contenido, etc. Veamos algunas opciones:
Autohospedado
Podemos escribir un servicio que se encargue del rastreo de nuestro propio sitio utilizando un navegador sin cabeza, como phantomjs o zombiejs, tomando una instantánea de la página con los datos representados y almacenándola como HTML. Siempre que vemos la cadena de consulta ?_escaped_fragment_
en una solicitud de búsqueda, podemos entregar la instantánea HTML estática que tomamos de la página en lugar de la página renderizada previamente solo a través de JS. Esto requiere que tengamos un backend que entregue nuestras páginas con lógica condicional en el medio. Podemos usar algo como el backend de prerender.io como punto de partida para ejecutar esto nosotros mismos. Por supuesto, todavía necesitamos manejar el proxy y el manejo de fragmentos, pero es un buen comienzo.
Con un servicio pago
La forma más fácil y rápida de introducir contenido en el motor de búsqueda es utilizar un servicio Brombone , seo.js , seo4ajax y prerender.io son buenos ejemplos de estos que albergarán la representación del contenido anterior. Esta es una buena opción para aquellos momentos en los que no queremos lidiar con la ejecución de un servidor/proxy. Además, suele ser súper rápido.
Para obtener más información sobre Angular y SEO, escribimos un extenso tutorial al respecto en http://www.ng-newsletter.com/posts/serious-angular-seo.html y lo detallamos aún más en nuestro libro ng-book: El libro completo sobre AngularJS . Compruébalo en ng-book.com .