Posted on January 12, 2015 in Code & Design
Observations on Front-end Routing & WordPress
Front-end frameworks are becoming wildly popular as a means of focusing more attention on the client side and giving sites that single page application feel. There are tons of articles on routing and accessing and displaying data for whatever front-end framework you’re using. However, I’ve found there to be a lack of documentation and resources for using front-end frameworks with the most popular CMS in the world: WordPress.
I’ve started to do quite a bit of research on using front-end frameworks with WordPress and the main issue I keep running into is that of routing. While front-end routing issues are not specific to just WordPress, my goal has been to figure out a solid solution to tackle front-end routing specifically related to WordPress.
The problem with front-end routing
Front-end routing works great by default and can be very simple to use with WordPress. That is, if you don’t care about SEO and search engine friendly URLs. By default, the routers built in to Backbone, Angular, Ember, etc. usually serve pages by way of hashtags. For example, the route for a super awesome article might be
http://coolsite.com/#super-awesome-article. Using the History API, the hashtag can be removed to serve a prettier URL like
You might think (as I did) that
What we can do to overcome SEO issues
There are, as I see it, two ways to provide web crawlers with content and still get that snappy, SPA feel of front-end routing.
1. Combine server routes and front-end routes
I’ve been playing around with this method and can say that it’s just a lot of work and duplication of concerns. Here’s an example of what it looks like to serve up a standard WordPress post.
- WordPress serves
/super-awesome-post, pulling from the
page.phptemplate. This is what search engines see.
- Use a Backbone (replace with your framework of choice) router to serve
- Replace all permalinks with something like
<a href="#/<?php echo $post->post_name;?>">so clicking on links uses the front-end routing solution.
While I still think this method has potential and could potentially be fully implemented, I’m finding it has more downsides than upsides to continue pursuing.
page.php for single pages,
<h1> <?php the_title(); ?> // What WP would see <%- post.title %> // What the JS templating engine would see </h1>
2. Serve HTML snapshots to crawlers
The next method that I have yet to fully test out is that of using hashbangs and serving HTML snapshots to crawlers. Google actually has some really good documentation on doing this, as they’ve recognized the rise of AJAX-y applications and the need to be able to index them.
Essentially, this method works by using
/#!super-awesome-post) in your URLs, which tells Google that this content is created dynamically on the front-end and to proceed with the next step.
The next step is where it gets tricky. You have to then tell crawlers where your static content actually is. It then reads that, but keeps your hashbang URL as the destination when users click on a search result.
Telling crawlers where your static content lives is done on the server side. My understanding of the process is that once a crawler sees the hashbang, it then requests the same URL, but with
_escaped_fragment_ in place of the
#!. Using WordPress, you’d first have to make sure that
/?_escaped_fragment_super-awesome-post maps to
/super-awesome-post. You’d then have to serve an HTML snapshot to
/?_escaped_fragment_super-awesome-post that contains static content.
HTML snapshots can be created in a multitude of ways. The thing that makes me cringe about HTML snapshots is that they appear to be pretty manual. Without some sort of server side script in place, it looks like you’d have to literally run a snapshot whenever you update your WordPress site (which can be quite frequent).
Google also lists a method of using a meta tag if you don’t want to use the hashbang format (
<meta name="fragment" content="!">).
This is complicated
Both methods I’ve talked about are damn complicated and tedious. But hey, that’s why I’m writing about this: to find the simplest solution for front-end routing with WordPress! I’m probably going to try out the second method with the hashbangs and HTML snapshots in the near future, so stay tuned for a follow-up post with actual code and hopefully a working demo.
Oh yeah, this is all possible courtesy of the WP REST API
I’ve spent the entirety of this article talking just about front-end routing, but I should note quickly that the use of front-end frameworks wouldn’t even be possible if we couldn’t fetch our WordPress data with AJAX. A project called the WP REST API essentially turns your WP data into JSON for easy access with AJAX and front-end frameworks. The plugin can be found here and will apparently be included in WordPress core coming up very soon.