Cómo saber qué errores JavaScript genera Google cuando ejecuta JavaScript

Publicado por Lino Uruñuela el 1 de febrero del 2021

Ya hemos visto cómo podemos comprobar y monitorizar qué URLs renderiza Google, pero si queremos ir un poco más allá también podemos capturar y guardar en Google Analytics qué errores JavaScript se producen cuándo Google ejecuta el código JavaScript para renderizar el contenido.

Cuándo los usuarios interaccionan con los elementos del HTML de una página, ya sea haciendo click en alguna parte de la pantalla o rellenando un formulario, o cargando imágenes mediante Lazy Load se usa JavaScript para ello, y este JavaScript se ejecuta en el navegador del usuario.

Eso quiere decir, que si se produce un error en ese código no podremos verlo ya que no queda registro en el servidor sino en el navegador del usuario. A veces los errores en JavaScript bloquean otras acciones que se deberían realizar pero que debido a algún fallo en el código no se hace y esto puede ser crítico ya que Google no vería ese contenido o elementos que deberían obtenerse mediante la ejecución JavaScript.

Ejemplo de error generado adrede para comprobar el código
Error JavaScript de prueba para comprobar el código

Para poder saber si existen errores críticos cuando Google ejecuta código JavaScript podemos aprovechar la misma solución que en el artículo de cómo monitorizar la ejecución de código JavaScript por parte de Google (para renderizar el contenido) aplicando unos ligeros cambios a nuestro código anterior

 

Código JavaScript

Para ello, al igual que la vez anterior capturaremos un evento JavaScript, concretamente con esta línea "window.addEventListener('error', function(e)" , para que cuando se produzca  se ejecute una función que nos permite trackear estos errores y anotarlos en Google Analytics de la misma manera que hicimos en el post anterior, con la diferencia de que esta función se ejecutará únicamente cuándo se genere un error JavaScript.

window.addEventListener('error', function(e) {
        var botPattern = "googlebot|Googlebot-Mobile|Googlebot-Image|Google favicon|Mediapartners-Google";
        var re = new RegExp(botPattern, 'i');
        var userAgent = navigator.userAgent; 
        if (re.test(userAgent)) {
            var client = new XMLHttpRequest();
            var ErroresURL='https://www.mecagoenlos.com/ErrorRenderizadaGoogle.gif?UrlOrigen='+window.location.href+'&mensajeError='+e.message+'&UA='+unescape(encodeURIComponent(userAgent))+'&LineaError='+e.lineno.toString();
        
            client.open('GET',ErroresURL);
            client.setRequestHeader('Content-Type', 'text/plain;charset=UTF-8');
            client.send(e);
    });	

Con este código, cuando se genere un error JavaScript, se ejecutará la función, desde la cual llamaremos a otro pixel transparente "ErrorRenderizadaGoogle.gif" añadiendo como parámetros la URL actual en la que está el usuario, el mensaje de error que devuelve el error y el User Agent, es decir hacemos una llamada a una URL de este tipo

https://www.mecagoenlos.com/ErrorRenderizadaGoogle.gif?UrlOrigen='+window.location.href+'&mensajeError='+e.message+'&UA='+unescape(encodeURIComponent(userAgent))

 

Configurar .htaccess

Como en el anterior post, en el fichero .htaccess crearemos las reglas para que cuándo se solicite la URL del pixel transparente sea otro fichero PHP el que se ejecute

RewriteCond %{REQUEST_URI} ErrorRenderizadaGoogle.gif
RewriteRule ErrorRenderizadaGoogle.gif(.*)$ https://www.mecagoenlos.com/ErrorRenderizadoJS.php$1

De esta forma, cuando se solicite la URL de la imagen "https://www.mecagoenlos.com/ErrorRenderizadaGoogle.gif" realmente se ejecutará nuestro fichero PHP "ErrorRenderizadoJS.php"

 

Fichero PHP

Desde este fichero se comprobará si es realmente Google el que está ejecutando ese código y crearemos una llamada a Google Analytics (mediante el protocolo de medición de Google Analytics) para generar un evento  que tendrá como categoría "Error-Renderizado-Googlebot", como acción del evento la URL  dónde se ha producido y en la etiqueta del evento añadiremos el mensaje de error JavaScript que se generó en el navegador del cliente.

header("Pragma-directive: no-cache");
header("Cache-directive: no-cache");
header("Cache-control: no-cache");
header("Pragma: no-cache");
header("Expires: 0");
$src = $_SERVER['HTTP_REFERER']; 
$UA=$_GET["UA"]; 
$mensajeError=$_GET["mensajeError"];
$tipo = getimagesize("ImagenRenderizadaGoogle.gif");
		$imagen = "ImagenRenderizadaGoogle.gif"; 
		
function comprobarGoogle($Ip){
    
        $hostname=gethostbyaddr($Ip);    
        $ip_by_hostname=gethostbyname($hostname);   
      if(preg_match("/googlebot/i",$hostname))
		if ($ip_by_hostname == $Ip)
			return true;
		else
			 return false;
		
		else
			 return false;
}
$botname="inicial";
$bots = array('Mediapartners-Google[ /]([0-9.]{1,10})' => 'Google Mediapartners',
	'Mediapartners-Google' => 'Google Mediapartners',
	'Googl(e|ebot)(-Image)/([0-9.]{1,10})' => 'Google Image',
	'Googl(e|ebot)(-Image)/' => 'Google Image',
	'^gsa-crawler' => 'Google',
	'Googl(e|ebot)(-Sitemaps)/([0-9.]{1,10})?' => 'Google-Sitemaps',
	'GSiteCrawler[ /v]*([0-9.a-z]{1,10})?' => 'Google-Sitemaps',
	'Googl(e|ebot)(-Sitemaps)' => 'Google-Sitemaps',
	'Mobile.*Googlebot' => 'Google-Mobile',
	'^AdsBot-Google' => 'Google-AdsBot',
	'^Feedfetcher-Google' => 'Google-Feedfetcher',
	'compatible; Google Desktop' => 'Google Desktop',
	'Googlebot' => 'Googlebot');

	foreach( $bots as $pattern => $bot ) {
		if ( preg_match( '#'.$pattern.'#i' , $UA) == 1 )
		{
		  $botname = preg_replace ( "/\\s{1,}/i" , '-' , $bot );
		  break;
		}
	  }

if(comprobarGoogle($_SERVER['REMOTE_ADDR']))
	$esGoogle="Real";
else
	$esGoogle="Fake";
class BotTracker  {
	
	static function track($s, $params){
			$bot = "";
			$data = array( 
				'v'	=> 1, 
				'tid'	=> 'UA-XXXXXX-1',
				'cid'	=> self::generate_uuid(), 
				't'	=> 'event',
				'dh'	=> $s['HTTP_HOST'], 
				'dl'	=> $s['REQUEST_URI'], 
				'dr'	=> $s['HTTP_REFERER'],	
				'dp'	=> $s['REQUEST_URI'], 
				'dt'	=> $params['page_title'], 
				'ck'	=> $s['HTTP_USER_AGENT'], 
				'uip'	=> $s['REMOTE_ADDR'],
				'ni'	=> 1,
				'ec'	=> 'Error-Renderizado-Googlebot',
				'el'	=> $params["mensajeError"]." (".$params['UA']." -" .$params['botname']." - ".$params['esGoogle'].")",
				'ea'	=> $params['URLrenderizada']
			);
			
			$url = 'http://www.google-analytics.com/collect';
			$content = http_build_query($data); 
	
			$ch = curl_init();
			curl_setopt($ch, CURLOPT_USERAGENT, $s['HTTP_USER_AGENT']);
			curl_setopt($ch, CURLOPT_URL, $url);
			curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
			curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 0);
			curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, 0);
			curl_setopt($ch, CURLOPT_TIMEOUT_MS, 0);
			curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type: application/x-www-form-urlencoded'));
			curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
			curl_setopt($ch, CURLOPT_POST, 1);
			curl_setopt($ch,CURLOPT_ENCODING , "gzip");
			curl_setopt($ch, CURLOPT_POSTFIELDS, $content);
			$result = curl_exec($ch);
			$info= curl_getinfo($ch);
			curl_close($ch);
		}
		static private function generate_uuid() {
		
		return sprintf( '%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
			mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ),
			mt_rand( 0, 0xffff ),
			mt_rand( 0, 0x0fff ) | 0x4000,
			mt_rand( 0, 0x3fff ) | 0x8000,
			mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff )
		);
	}
}
 BotTracker::track($_SERVER, array("page_title"=>"Renderizado JS Google","URLrenderizada"=>$src,"esGoogle"=>$esGoogle,"mensajeError"=>$mensajeError,"botname"=>$botname,"UA"=>$UA));
?>


 

Ahora ya podemos ver qué errores genera Google cuándo ejecuta JavaScript para renderizar el contenido

 

Ver qué errores genera Google al ejecutar JavaScript y en qué URLs ocurre

Con esta implementación podremos ver los errores concretos que Genera Google cuando ejecuta el código JavaScript, y podemos ver en qué URLs se producen.

Errores JavaScript generados por Google

Se me ocurren muchas otras cosas a monitorizar en cuanto a la ejecución de JavaScript por parte de Google, como por ejemplo podríamos crear una solución similar para saber si Google realiza determinadas acciones, como hacer scroll, o clicks, o cualquier otro evento mediante JavaScript, pero con esto finalizamos por hoy las publicaciones, en breve más!

 

 



Últimos posts

Últimos comentarios


Quentin
Very good list, thx !
Post: Expresiones regulares para SEO (Google Search Console)

Javier
Gracias Lino!
Post: Expresiones regulares para SEO (Google Search Console)

Lino
Hola Marcos, muy buena observación y sí, es tal como dices, o al menos yo percibo eso. El otro día lo comenté en el evento de ClickSeo
Post: Links y experimentos

Marcos
Hola Lino, gracias por tu excelente Blog Estuve replicando tu experimento, y vi lo siguiente: > Hice 3 pruebas, y no puedo posicionar co
Post: Links y experimentos

Lino
Hola @RicOriFra sí lo hay :), al vídeo sobre Search Console en el SEonthebeach
Post: Logs y Big Data

Lino
Hola @davidzslv sí me aparecieron, pero no siempre :s. Creo funciona igual que desde el Inspector, es decir, cuando quiere la indexa y cuá
Post: Solicitar indexación de una URL usando API Indexing + API Explorer

David
Estupendo, es justo lo que necesitaba, ¿al final te aparece en las serps?
Post: Solicitar indexación de una URL usando API Indexing + API Explorer

Lino
Hola @acoutin te estoy usando de pruebba, esta será la última :)
Post: Google podria no querer el HTML de una URL

Lino
@Pedro Amador ¿y funciona bien?
Post: Solicitar indexación de una URL usando API Indexing + API Explorer

Pedro Amador
¡Excelente truco Lino! Ya ha pasado a estar en mi rutina del día a día.
Post: Solicitar indexación de una URL usando API Indexing + API Explorer