When we started working on our new website, we quickly faced challenges often encountered with single-page application frameworks: enabling search engine optimization (SEO) and crawlability. The problem with these kinds of applications is that you only have one .html host file, which has two important consequences:
- Having only one title tag makes it hard for people to use the browser history for navigation
- It becomes impossible to define meta properties with relevant data for different site sections
Thankfully, each of these problems can be solved.¨
- Changing the title
- Adding and updating meta properties
- Making the application crawlable
Changing the title
This is actually a simple fix. We can use GWT’s
Document class to change the title when our section is attached to the DOM:
Adding and updating meta properties
The hard way
We could create
MetaElements and inject them into the head section manually when our section is attached to the DOM :
This seems a bit cumbersome and isn’t quite what webmasters are used to, so perhaps we can do better. This is where GWT-SEO comes into play. It allows us to define meta properties in the
UiBinder’s ui.xml file as a
Widget, almost like we would define them in an html file. The library will then create and inject the defined meta elements in the head section when your View is attached to the DOM, removing the need to register your own
Now that’s better! Notice that the title is also handled, which means no more document.setTitle() is needed either!
Moreover, since we’re within a
UiBinder, we can therefore take advantage of the power of ui:msg to internationalize our properties (more details on using GWT i18n with UiBinder in an upcoming post!). In the meantime, you can take a look at our website for a live example of GWT-SEO using i18n, and especially at the sources of the website to see more in details how it was done, or at the source of my bee page for a specific example.
More often than not, when implementing a single-page application, the content of the section will depend on some data fetched from an AJAX request (e.g. : a product page in an online store). GWT-SEO can also help you with that, although it requires some Java code in your request’s callback. Let’s say we have a Presenter that retrieves a Product when the product’s dynamic page is loaded, and passes it to its View through the setProduct method.
The advantage of using GWT-SEO, versus manually creating
MetaElements to inject dynamic properties, is that it prevents duplicates by replacing existing properties with new ones, by leveraging the injection of derived tags (title and og:title, description and og:description, etc.).
But what good would all that do if crawlers like Google or Facebook can’t retrieve the fully rendered version of the page?
Making the application crawlable
Making your application crawlable could be the topic of a whole other blogpost, but I will discuss it briefly here.
Most crawlers nowadays implement a simple directive that allows us to serve different content when a hashbang (#!) is encountered in an URL. So the first step is to make sure your section URLs contain hashbangs. For example, a crawler fetching
http://www.arcbees.com/#!/support would replace the hashbang with the escaped_fragment query parameter, in this case :
http://www.arcbees.com/?_escaped_fragment_=/support (take a look at the rendered DOM).
Rendering for crawlers
Now that we have a way to identify crawlers’ requests, we need to serve a rendered version when we detect the
Writing the meta properties for all the sections of your single-page application will allow you to be better ranked on search engines, and give you a chance to stand out against your competitors. It will also make your pages easier to share across social medias, which is, in this 2.0 era, mandatory for any web page. SEO and crawlability are easy things to overlook when developing your application, but to ignore them is to miss out on a substantial number of potential visitors!