Async local pages, SEO and iframes


JavaScript Zeptojs SEO iframes Async

As you most probably know, crawlers don't like iframes. If they even read them, they associate the iframe's content to the parent page. I had to face a problem about pages being loaded asynchronously building the layout for my 2nd generation website (i.e. the one you can see now in May 2014).

The one-page design is often used for portfolios. My website is a portfolio and a blog at the same time. I wanted a one-page design. So how could I load the articles without having to reload the page?

I had three options:

In this case, as data isn't loaded on DOM ready, the headless browser technique is not an option.

In this article I'll show you the technique I created ad-hoc for my website.


Before commenting my code, I'll expose my solution: crawlers are stupid, they are able to read HTML documents and in some rare cases execute a little bit of javascript. I thus had to create a HTML solution able to redirect the crawler to a readable content, outside the iframe.

The easiest solution would be to create an article layout which doesn't have any element but the article's body. That's fine, it's indexable (somehow, see later), but it's poorly internal linked; also people coming from Google would see the article without any other element (header, footer, menu...).

So what? Simply create the article's layout exactly like we would create a single-page layout, thus including ANY element we need. But then the iframed content would show double elements (again header, footer, menu, whatever). This is where my solution takes place.

The idea: create links to the articles in the main page with the "complete" article's layout; JavaScript will intercept the clicks on these links and add a parameter (in my example: a nomenu GET variable) and set the anchor's target to the iframe, all of this only if the user agent is not a crawler. This will produce the following logic flow:


Let's see how I did it.

First of all, how are we calling the pages? Using simple, crawler-friendly anchors, pointing to the stand-alone article with optional elements (like the menu). We're adding the data-target attribute in order to intercept these calls and redirect the target to the named iframe.

:::HTML
<a href="/my/local/page" data-target="more-content">My article!</a>

Secondly a little bit of JavaScript. I used Zeptojs, you're free to use pure JavaScript, jQuery or any other library of course.

:::JavaScript
// I used data-target to recognise the internal links
$('a[data-target="more-content"]').click(function (event) {
    // if you're a crawler, the anchor is just fine
    if (/bot|googlebot|crawler|spider|robot|crawling/i.test(navigator.userAgent)) {
        return;
    }

    // CRAWLERS WILL NEVER EXECUTE THIS CODE

    // 1. change the event's target with the iframe named (not id) 'more-content' (in my particular case)
    // default target is '_self'
    event.target.target = $(this).data('target');

    // 2. change the href adding the 'nomenu' variable
    // will add the variable to the GET array

    if (!/.*[\?|&]nomenu$/.test(event.target.href)) {
        // the link already has GET parameters
        if (/.*\?.*/.test(event.target.href)) {
            event.target.href +=  '&nomenu';
        } else { // the link has no GET parameters yet
            event.target.href +=  '?nomenu';
        }
    }

    // 3. The end. In case you're hiding the iframe, it's time to show it.
});

That's all the JavaScript you need, if you'll handle the nomenu GET variable server-side. In my particular case, PHP will simply add the nomenu class to the body and the CSS will hide the menu (with a simple display: none).

Also, if you're using hash anchors to navigate in the website, you'll have to prefix the website's main URL to the menu's hash links. (i.e. from #blog to http://mywebsite.com/#blog)


PROs using this method:

CONs:

- 3rd May 2014

> back