Le problème des applications JavaScript est qu'elles ne sont pas crawlable, il est impossible pour un moteur de recherche d'avoir accès à toutes ses informations. Or les interfaces ajax se sont développé énormément depuis quelques années avec la mode du Web 2.0 et la technologie Ajax.

Google a fait une proposition et la mise en oeuvre dans son indexeur pour résoudre ce problème. Il en a parlé initialement sur le blog : http://googlewebmastercentral.blogspot.com/2009/10/proposal-for-making-ajax-crawlable.html, un site dédié à cette technique est maintenant disponible : http://code.google.com/web/ajaxcrawling/

Nous allons développé cette technique dans cet article que nous venons de mettre en place sur le site mobile de SFEIR qui a été réalisé en GWT avec le framework Modding.

Principe d'utilisation

Google part du constat que s’il rencontre un lien contenant une ancre commençant par le signe "!", ce lien ajax doit être indexé. Il va alors rappeler la page en prenant le nom de l'ancre et en la passant en paramètre de la page _escaped_fragment_=

Seulement les liens avec une ancre commençant par un "!" seront indexé, cela permet de contrôler l'indexation et ne pas se retrouver avec tous le contenu de notre application indexé par Google.

Exemple :
monsite.com/page.html#!url_ajax
Deviendra :
monsite.com/page.html?_escaped_fragment_=url_ajax

La première URL est l'URL publique, ce que l'on doit mettre en lien depuis tous les sites où l'on veux avoir un lien, l'application JavaScript doit donc ouvrir automatiquement la page url_ajax dans l'application à son ouverture.

La deuxième URL est utilisé uniquement par Google, et ne doit pas être mis en lien, elle doit retourner la version HTML de la page, c'est à dire ce qu'on aurait si on exportait l'HTML généré par notre application JavaScript si on va sur la première URL. Il est donc nécessaire que le serveur analyse l'URL et si il détecte le paramètre _escaped_fragment_, le serveur génére la version HTML de la page.

Google indexera ainsi le contenus de cette page HTML, mais dans les résultats du moteur de recherche, il affichera la première URL à l'utilisateur.

Mise en place dans une application JavaScript


Pour cela, il faut commencer par modifier son application JavaScript pour utiliser la gestion de l'Historique :
Pour les projets GWT, une api permet de le faire simplement en utilisant History : http://code.google.com/webtoolkit/doc/latest/DevGuideCodingBasicsHistory.html

History.getToken(); //Permet de récupérer le token
History.addValueChangeHandler(new ValueChangeHandler<String>() {
public onValueChange(ValueChangeEvent<String> event) {
event.getValue();
//Permet de récupérer les changements du token
}
};
History.newToken("!url_ajax"); //Ajoute un nouveau token



Notre framework Modding depuis sa version 0.3 est maintenant capable de démarrer une autre activité que l'activité principale lors du chargement de la page avec l'information dans l'url :
http://m.sfeir.com/#!com.sfeir.client.activity.PageActivity?hash=4&url=page%252Fjava.html


Ce liens lancera directement la page "Notre savoir faire / Expertise Java" sans afficher le premier menu disponible normalement :
http://m.sfeir.com


Un autre projet créé par Alexandre Thiel également chez SFEIR, permet de créer une application GWT en utilisant la notation Rest : http://code.google.com/p/restful-gwt/

Mise en place sur le serveur de la version HTML

Il faut maintenant modifier le serveur pour détecter que Google demande la version HTML ou pas, pour cela il faut détecter si le paramètre _escaped_fragment_ existe bien.
http://m.sfeir.com/?_escaped_fragment_=com.sfeir.client.activity.PageActivity?hash=4%26url=page%252Fjava.html

Pour cela, on peux facilement le faire en utilisant un filtre, qui vous permettre de choisir entre afficher la page habituelle ou la version HTML.

Pour cela, il est nécessaire de renommer le fichier html en jsp car il n'est pas possible en Java d'ajouter un filtre sur une page HTML. Ensuite, la configuration du fichier de configuration est très simple dans le fichier web.xml, en ajoutant simplement les balises filter et filter-mapping :
  <filter>
<filter-name>crawler</filter-name>
<filter-class>com.sfeir.server.CrawlerFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>crawler</filter-name>
<url-pattern>*</url-pattern>
</filter-mapping>

Voyons maintenant le fonctionnement de la classe :




Le filtre pour chaque requête, vérifie si le paramètre _escaped_fragment est présent, sinon il lance la chaine suivante des filtres avec le chain.doFilter(request, response);

Dans le cas où la requête est une requête de google pour indexer la page Ajax, on reconstruit l'url originale avec l'ancre ajax.

Il reste donc à produire le code HTML, pour cela, il y a deux stratégies, soit en fonction de l'url, produire la page html en utilisant les technologies habituelles de java : jsp, spring, velocity, etc ...
Soit utiliser un navigateur internet léger comme HtmlUnit pour construire la page directement en utilisant l'application JavaScript.

La deuxième approche conseillée par Google a le mérite d'être simple à mettre en place car on utilise le code de notre application. Voici un exemple d'utilisation avec HTMLUnit :
WebClient webClient = new WebClient(BrowserVersion.FIREFOX_3);
webClient.setThrowExceptionOnScriptError(false);
webClient.setJavaScriptEnabled(true);
HtmlPage page = webClient.getPage(pageName);
webClient.setTimeout(10000);
out.println(page.asXml());
webClient.closeAllWindows();


Le timeout dépend de votre application, et du temps nécessaires pour que le code javascript s'exécute, que les services soient appeler, et que le rendu final soit fait !
Cela peux donc prendre du temps et des ressources.

Pour le site mobile de sfeir, nous avons utilisé la première approche, car le site est hébergé sur Google App Engine, et la bibliothèque n'est pour l'instant pas compatible avec App Engine, le portage est en cours. De plus, nous sommes limité par le temps d'exécution des pages à 30 secondes.
Comme le site mobile est statique, réaliser la version HTML était assez facile, simplement à lire les fichiers HTML normalement chargés par la partie GWT et les écrirent dans la réponse du serveur.

Testons l'indexation

Cette article explique le fonctionnement préconisé par Google pour rendre ses applications indexable, et plus particulièrement les application GWT en Java.
C'est pour Sfeir, l'occasion de mettre en pratique et de lancer un test grandeur nature de ce référencement.

Merci de nous y aider en ajoutant des liens depuis vos sites vers une page particulière de notre site mobile pour tester l'indexation dans Google.

Cette expérimentation nous permettra ensuite de valider la technologie pour l'utiliser chez nos clients et vos clients.