How to enhance SEO in an Ajax application

Before we started to discuss on this topic, I assume that you should be already familiar with how the Ajax applications work. Hence, this article was written merely for showing us that it’s possible for not sacrificing the SEO(i.e. Search Engine Optimization) in a web application that uses Ajax for enhancing it’s user-friendliness. Of course, there would be more works involved for implementing the SEO in an Ajax application.

Let says we has implemented Ajax in a news portal site. Then, your codes for getting the news details through Ajax would probably like:
<a href=”javascript:getNewDetailsByAjax(1);” >News item 1</a>
<a href=”javascript:getNewDetailsByAjax(2);” >News item 2</a>
<a href=”javascript:getNewDetailsByAjax(3);” >News item 3</a>

It’s nothing wrong with the codes shown above; but it’s certainly not search engines friendly. Because the search engines will not index those “links” like “javascript:getNewDetailsByAjax(1);”, “javascript:getNewDetailsByAjax(2);” and “javascript:getNewDetailsByAjax(3);”. It’s simply because such “links” aren’t URLs. Furthermore, as all of the news items might share the same <title>page title</title>, the search engines might most likely to index only a single page(if there is any page being indexed).

Ok, without considering about Ajax at the first place, the solution for handling the SEO issues as stated above might look like:
<a href=”http://www.example.com?id=1&type=details” >News item 1</a>
<a href=”http://www.example.com?id=2&type=details” >News item 2</a>
<a href=”http://www.example.com?id=3&type=details” >News item 3</a>

Without any doubt, it should be now more search engines friendly. Because the possibility for the URLs like “http://www.example.com?id=1&type=details” to be indexed by the search engines will be much higher than the “link” with pattern like “javascript:getNewDetailsByAjax(1);”. Besides, as the title of the page always plays an important role in SEO. Hence, a unique page title should be created now for each news item. However, as we have taken out the Ajax features from the hyperlinks of those news items, the browser right now need to refresh the whole page every time for getting a selected news item. Such situation(i.e. without Ajax) will of course cost more bandwidth usage, slower response speed, less user-friendly & etc.

Therefore, more works are needed for fulfilling the requirements(i.e. SEO + Ajax). My solution is shown as below:

<script language=”javascript” type=”text/javascript”>
    /**************** Start : Common Functions Part *****************/
    /***
    Function : getElementsByClassName
    Description : To get the element by class name.
    */
    document.getElementsByClassName = function(strCssClassName) {
        var docList = this.all || this.getElementsByTagName('*');
        var matchArray = new Array();

        /* Create a regular expression object for class */
        var re = new RegExp("(?:^|\\s)"+strCssClassName+"(?:\\s|$)");

        for (var i = 0; i < docList.length; i++) {

            if (re.test(docList[i].className) ) {
                matchArray[matchArray.length] = docList[i];
            } // - end: if
        } // - end: for

        return matchArray;
    }

    /***
    Function : getUrlParam
    Description : To get the url params by name.
    */
    function getUrlParam(name, url) {
        name = name.replace(/[\[]/,”\\\[”).replace(/[\]]/,”\\\]”);

        var regexS = “[\\?&]”+name+”=([^&#]*)”;
        var regex = new RegExp(regexS);
        var results = regex.exec(url);

        if( results == null ) {
            return “”;
        }
        else {
            return results[1];
        } // - end: if
    }
    /************** End : Common Functions Part ****************/

    /***
  * Start : To fire the DomOnLoad function once the DOM for the page has been constructed or loaded.
  * It’s more advantageous over the window.onload.
  * As it need not to wait all the images, flash objects & etc to be finish loaded first.
  */
    var bolDomLoaded = false;

    if(typeof DomOnLoad == ‘function’) {

        if (document.addEventListener && bolDomLoaded == false) { // For Firefox
            document.addEventListener(”DOMContentLoaded”, function(){bolDomLoaded = true; DomOnLoad();}, false);
        }
        else if (/Safari/i.test(navigator.userAgent)){ // For Safari
            var _timer = setInterval(function(){

                if(/loaded|complete/.test(document.readyState) && bolDomLoaded == false){
                    clearInterval(_timer);
                    bolDomLoaded = true;
                    DomOnLoad(); // call target function
                } // - end: if
            }, 10);
        }
        else if (document.all && !window.opera) { // For IE
            document.write(’<script type=”text/javascript” id=”contentloadtag” defer=”defer” src=”javascript:void(0)”><\/script>’);
            var objContentLoadTag = document.getElementById(”contentloadtag”);

            objContentLoadTag.onreadystatechange = function(){

                if ((this.readyState == “complete” || this.readyState == “loaded”) && bolDomLoaded == false){
                    bolDomLoaded = true;
                    DomOnLoad();
                } // - end: if
            }
        } // - end: if else
    } // - end: if
    /***
    * End : To fire the DomOnLoad function once the DOM for the page has been constructed or loaded.
    */

    /***
    Function : addEventsByClassName
    Description : To add new events to a HTML element by the name of css class(i.e.currently only for onclick event).
    */
    function addEventsByClassName(arrCssClasses){

        for(j = 0; j < arrCssClasses.length; j++) {

            strCssClass = arrCssClasses[j];
            objElements = document.getElementsByClassName(strCssClass);

            for(i = 0; i < objElements.length; i++){

                // - Onclick Event
                objElements[i].onclick = function(){
                    var strTitle = this.title || this.name || null;
                    var strUrl = this.href || this.alt;
                    var strRel = this.rel || false;

                    eval(strCssClass + “(strUrl, strTitle, strRel);”);
                    //alert(getUrlParam(’name’, this.href));
                    this.blur();

                    if(window.event) {
                        event.returnValue = false;
                    }
                    else {
                        return false;
                    } // - end: if else
                };
                // - Further Events…
            } // - end: for
        } // - end: for
    }

    /***
    Function : DomOnLoad
    Description : It will be called once the DOM for the page has been constructed or loaded.
    */
    function DomOnLoad() {
        var arrCssClasses = Array(’getnewsdetails’);
        addEventsByClassName(arrCssClasses);
    }

    /***
    Function : window.onload
    Description : As a backup solution to the other browsers in which failed to call the DomOnLoad function.
    */
    window.onload = function(){
        setTimeout(”if(!bolDomLoaded){addEventsByClassName(Array(’getnewsdetails’));}”, 0);
    }

    /***
    Function : getnewsdetails
    Description : It’s name must be same as the CSS class in the SEO-Ajax activated hyperlinks.
    */
    function getnewsdetails(strUrl, strTitle, strRel) {
        id = getUrlParam(’id’, strUrl);
        getNewDetailsByAjax(id);
    }
</script>

<a class=”getnewsdetails” href=”http://www.example.com?id=1&type=details” >News item 1</a>
<a class=”getnewsdetails” href=”http://www.example.com?id=2&type=details” >News item 2</a>
<a class=”getnewsdetails” href=”http://www.example.com?id=3&type=details” >News item 3</a>

By following the example shown above, we will be able to apply both SEO and the Ajax technologies in an web application at the same time.

Note : SEO-Ajax activated hyperlinks here refers to those hyperlinks in which cater for both SEO and Ajax technologies at the same time. Such as the link - <a class=”getnewsdetails” href=”http://www.example.com?id=1&type=details” >News item 1</a> shown in the example above.

February 26th, 2009 @ 12:10 AM • Filed under General

No Comments

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a comment

You must be logged in to post a comment.