How to easily display a twitter feed using javascript

on March 15, 2012 by Downloads, Programming, Social Media, Technology, Web Programming & Development with 26 comments

Update: March 2013

This method of retrieving timeline data from Twitter is going to be shut down very soon. Please see my follow up article on the death of the Twitter API v1 for more details on why it will no longer be possible to use JavaScript for the Twitter API.


Twitter. For better or worse it’s everywhere. You’d be hard pressed to find a new website or blog that is not incorporating a twitter feed into the site somewhere. There are tons of plugins, libraries, and extensions that help you get up and running with a twitter feed quickly, but many times they can be overkill for what you need.

One of the great things about twitter is how accessible it is. The team at twitter has done a really good job of creating an API that is simple, powerful, and flexible all at the same time. If you just need to read a single timeline (your own or someone else) you can skip all the 3rd party plugins and libraries and just roll your own JavaScript solution.

The example I’m going to discuss could be used to read a list of status updates for a user, or just the latest tweet, and display it anywhere you like in a website or blog. For convenience sake I’m using jQuery since we are generally using it in every project these days anyway.

Getting the data URL

Twitter’s API is pretty straight forward, you can get to whatever data you need with ease by reading their REST documentation. In our case, we are using the Get Statuses method call. The syntax is:

https://api.twitter.com/1/statuses/user_timeline/CypressNorth.json?callback=?&count=1

In our case we are limiting the response to 1 because we are only concerned with the latest tweet. If you remove the count parameter you get back the most recent 15 status updates. You can use the same URL to get the timeline of the account you are interested in, just replace cypressnorth.json with youraccountname.json.

Similarly, if you’d prefer to work with XML, you can change the extension of the request to youraccountname.xml and XML will be returned.

Making the AJAX Request

Now that we know the URL to retrieve our data, it’s time to make the request. In my case I’m only interested in working with JSON data, so to save time I can use the jQuery $.getJSON() function to both make the request and parse the results. An added benefit of using this shortcut is that it is compatible with Internet Explorer so you don’t need to make a separate XDR request.

$(document).ready(function() {
	loadLatestTweet();
});

function loadLatestTweet(){
	var _url = 'https://api.twitter.com/1/statuses/user_timeline/CypressNorth.json?callback=?&count=1';
	$.getJSON(_url,function(data){
		//data is holding a JSON object
	});
}

We now have the timeline back as JSON in the data object.

Building the HTML

Now that we have the status update, we need to display it somewhere. An easy way to do it is to create a <DIV> element with a unique ID for your twitter feed like so:

<div id="twitter-feed"></div>

Using jQuery, you can fill this div with the twitter response:

function loadLatestTweet(){
	var _url = 'https://api.twitter.com/1/statuses/user_timeline/CypressNorth.json?callback=?&count=1';
	$.getJSON(_url,function(data){
		var tweet = data[0].text;
		$("#twitter-feed").html('<p>'+tweet+'</p>');
	});
}

You have successfully retrieved your twitter status update and placed it on the page. The trouble is, it looks terrible and is pretty useless at the moment. Usually when you see a twitter post, it has links to the @Users and #hashtags mentioned in the posts and shows the date stamp of the update.

Parsing the Response

To make the status update more friendly and meaningful, we want to parse out any URL’s, @Usernames, and #Hashtags so that they are links. In addition we want to parse the date stamp of the update into a nice format which links to the original status update. To do that, we have a date parsing function and 3 JavaScript extensions to make our lives easier (thank you to Simon Whatley for the prototype extensions).

//Twitter Parsers
String.prototype.parseURL = function() {
	return this.replace(/[A-Za-z]+://[A-Za-z0-9-_]+.[A-Za-z0-9-_:%&~?/.=]+/g, function(url) {
		return url.link(url);
	});
};
String.prototype.parseUsername = function() {
	return this.replace(/[@]+[A-Za-z0-9-_]+/g, function(u) {
		var username = u.replace("@","")
		return u.link("http://twitter.com/"+username);
	});
};
String.prototype.parseHashtag = function() {
	return this.replace(/[#]+[A-Za-z0-9-_]+/g, function(t) {
		var tag = t.replace("#","%23")
		return t.link("http://search.twitter.com/search?q="+tag);
	});
};
function parseDate(str) {
    var v=str.split(' ');
    return new Date(Date.parse(v[1]+" "+v[2]+", "+v[5]+" "+v[3]+" UTC"));
}

Using these methods we can create a nice looking and helpful status update with ease:

function loadLatestTweet(){
	var _url = 'https://api.twitter.com/1/statuses/user_timeline/CypressNorth.json?callback=?&count=1';
	$.getJSON(_url,function(data){
		var tweet = data[0].text;
		var created = parseDate(data[0].created_at);
                var createdDate = created.getDate()+'-'+(created.getMonth()+1)+'-'+created.getFullYear()+' at '+created.getHours()+':'+created.getMinutes();
                tweet = tweet.parseURL().parseUsername().parseHashtag();
		tweet += '<div class="tweeter-info"><div class="uppercase bold"><a href="https://twitter.com/#!/CypressNorth" target="_blank" class="black">@CypressNorth</a></div><div class="right"><a href="https://twitter.com/#!/CypressNorth/status/'+data[0].id_str+'">'+createdDate+'</a></div></div>'
		$("#twitter-feed").html('<p>'+tweet+'</p>');
	});
}

*Note: The reason for the parseDate() function is to normalize the date format as it is not the same across browsers. If you skip that step it may fail in Internet Explorer (surprise).

Full Solution

Bringing it all together you have the full script ready for use, all you need to do is edit the HTML and CSS to suite your needs.

You can download the script and sample HTML file here: Twitter-Feed-Reader.zip

$(document).ready(function() {
	loadLatestTweet();
}); 

//Twitter Parsers
String.prototype.parseURL = function() {
	return this.replace(/[A-Za-z]+://[A-Za-z0-9-_]+.[A-Za-z0-9-_:%&~?/.=]+/g, function(url) {
		return url.link(url);
	});
};
String.prototype.parseUsername = function() {
	return this.replace(/[@]+[A-Za-z0-9-_]+/g, function(u) {
		var username = u.replace("@","")
		return u.link("http://twitter.com/"+username);
	});
};
String.prototype.parseHashtag = function() {
	return this.replace(/[#]+[A-Za-z0-9-_]+/g, function(t) {
		var tag = t.replace("#","%23")
		return t.link("http://search.twitter.com/search?q="+tag);
	});
};
function parseDate(str) {
    var v=str.split(' ');
    return new Date(Date.parse(v[1]+" "+v[2]+", "+v[5]+" "+v[3]+" UTC"));
} 

function loadLatestTweet(){
	var _url = 'https://api.twitter.com/1/statuses/user_timeline/CypressNorth.json?callback=?&count=1';
	$.getJSON(_url,function(data){
		var tweet = data[0].text;
                var created = parseDate(data[0].created_at);
                var createdDate = created.getDate()+'-'+(created.getMonth()+1)+'-'+created.getFullYear()+' at '+created.getHours()+':'+created.getMinutes();
                tweet = tweet.parseURL().parseUsername().parseHashtag();
		tweet += '<div class="tweeter-info"><div class="uppercase bold"><a href="https://twitter.com/#!/CypressNorth" target="_blank" class="black">@CypressNorth</a></div><div class="right"><a href="https://twitter.com/#!/CypressNorth/status/'+data[0].id_str+'">'+createdDate+'</a></div></div>'
		$("#twitter-feed").html('<p>'+tweet+'</p>');
	});
}

UPDATE API 1.1

To load more than just the latest tweet, modify the loadLatestTweet() function to look like the following (and change the count parameter to the number of tweets you want):

function loadLatestTweet(){
	var numTweets = 1;
    var _url = 'https://api.twitter.com/1/statuses/user_timeline/CypressNorth.json?callback=?&count='+numTweets+'&include_rts=1';
    $.getJSON(_url,function(data){
    for(var i = 0; i< data.length; i++){
            var tweet = data[i].text;
            var created = parseDate(data[i].created_at);
            var createdDate = created.getDate()+'-'+(created.getMonth()+1)+'-'+created.getFullYear()+' at '+created.getHours()+':'+created.getMinutes();
            tweet = tweet.parseURL().parseUsername().parseHashtag();
            tweet += '<div class="tweeter-info"><div class="uppercase bold"><a href="https://twitter.com/#!/CypressNorth" target="_blank" class="black">@CypressNorth</a></div><div class="right"><a href="https://twitter.com/#!/CypressNorth/status/'+data[i].id_str+'">'+createdDate+'</a></div></div>'
            $("#twitter-feed").append('<p>'+tweet+'</p>');
        }
    });
}
The following two tabs change content below.

Matthew Mombrea

Matt is a longtime entrepreneur and software engineer. He is a founder of Cypress North, and chief technology officer. Matt also contributes to the community as a columnist on ITworld.com.

26 Comments

  • Thomas van Zuijlen
    on March 19, 2012 Reply

    Thanks for the easy-to-follow guide, Matt!

    Something to take note of with regard to date parsing: The code you’ve posted here, will produce a zero-based month number (e.g. created.getMonth() returns a ’2′ for March) and a day number based on the day of the week rather than that of the month (e.g. created.getDay() returns a ’0′ for Sundays).

    To hammer out a more human-comprehensible date display, I’ve substituted line 32 of your Full Solution code example with the following:

    var createdDate = created.getDate()+’-’+(created.getMonth()+1)+’-’+created.getFullYear()+’ at ‘+created.getHours()+’:’+created.getMinutes();

    So adding 1 to the month obtained from created.getMonth, and replacing the week-based created.getDay with the month-based created.getDate. Also, I’ve added created.getFullYear() to get the tweet’s year.

    The above line results in something like ’19-03-2012 at 15:21′ for March 19th, 3:21 PM.

    Hope this is a decent addition to your solution!

    • Matt Mombrea
      on March 19, 2012 Reply

      Thanks Tom, I’ve updated the solution with your contribution. I admit the date formatting was done hastily, In the actual project I was using the jQuery DateFormat extension but refactored it out of the example. I should have done more testing!

      • Thomas van Zuijlen
        on March 19, 2012 Reply

        Ah, I see. Thanks for the quick reply – and thanks again for the clever solution.

  • Mike
    on May 7, 2012 Reply

    I think there might be a typo in the code. When I run the example, I get the following error:

    Uncaught SyntaxError: Unexpected token . it seems there is a missing + before
    ‘created.getHours()+’

    It should be ‘+created.getHours()+’

    I’m a noob. So forgive me if I’ve just embarrassed myself. ;)

    • Matt Mombrea
      on May 7, 2012 Reply

      You are quite right, thanks for the catch. I’ve updated the post as well as the example project.

  • Eric
    on September 5, 2012 Reply

    Hey Matt!

    First of all, nice work!

    I have noticed one thing that’s not working tho(assuming I’ve done it all correctly). If I set the count to, let say, five and on the timeline I’m displaying there are 3 tweets, 1 retweet and then 1 more tweet. The script only displays a total of 4 tweets instead of just showing the next tweet(making it five). Or why not show retweets aswell?

    The reason why this is important to me is that I have a client who want to display the 5 latest tweets and I can’t really tell them not to retweet anything or else they’ll mess it up.

    Is there a solution for this? Let me know if you need any code etc.

    Cheers!
    /Eric

    • Matthew Mombrea
      on September 5, 2012 Reply

      Eric,

      Thanks! This example is not currently set up for multiple tweets, just the latest 1. To modify it to handle more tweets you’ll need to change the function loadLatestTweet(). I’ve added an example to the end of this post.

  • Eric
    on September 6, 2012 Reply

    Hey Matt,

    Thanks you for the quick response! Your solution worked great but there is still the problem with the feed skipping retweets and thus showing the incorrect tweetcount.

    Is this something that can be fixed? Either show all posts on the chosen timeline or continue to pick just the tweets, ignore all the retweets and still show the correct count.

    Cheers,
    Eric

    • Matthew Mombrea
      on September 6, 2012 Reply

      Eric,

      My mistake. It doesn’t look like version 1 of the API includes retweets in the feed but does count them toward your max results. I’ve updated the example to use the API v1.1 with the include_rts=1 flag set which seems to work better. I’ve also updated the project file download to reflect this change. I think that should solve the issue for you.

  • Eric
    on September 7, 2012 Reply

    Matt,

    That’s just great! Thank you so much for your expertice and quick response.

    All the best,
    Eric

  • Dave
    on October 1, 2012 Reply

    Hi, thanks for explaining and sharing! I looked at the .js file and it doesn’t look like you’re using the API 1.1. I’ve been trying to understand how that works because we need to Authenticate to get the data back from Twitter.

    Have you been able to make this approach work with the 1.1 API?

    Kind regards,
    Dave

  • Adam J
    on October 11, 2012 Reply

    Thanks so much for this. I’ve been looking for examples of 1.1 recent tweet widgets. This was perfect. They should really have more straightforward documentation on the twitter dev site.

  • kevin
    on October 11, 2012 Reply

    Thanks for that, i’ve been looking for a while for a reliable solution. This works just fine.

  • Johan Danforth
    on October 24, 2012 Reply

    Hi, good post but you’re not Calling the version 1.1 api, which requires oauth to work. Version 1.0 of the api is said to stop working in april 2013 :/

  • Sean C
    on January 26, 2013 Reply

    Thanks for this clear well-written post, but would also love to see an update that addresses the recent 1.1 changes to the Twitter api which requires OAuth.

  • chris
    on February 18, 2013 Reply

    How would I go about changing the text colour? I have tried CSS and that changes everything but the hashtag, date and username?

    Cheers
    Chris

    • Matthew Mombrea
      on February 18, 2013 Reply

      Chris,

      You can add a css style for the following selector:
      #twitter-feed p{color:green;}

  • Apostolis
    on March 4, 2013 Reply

    Maybe it’s a bit late for this party guys but a have a noobie question. The first line of code with the https where should I put it? I can imagine after the in terms of getting the data etc. but I can’t put it in a tag because it treats the “//” as a comment in JavaScript language. Sorry I am so new in JavaScript / jQuery.
    Cheers!

    • Matthew Mombrea
      on March 4, 2013 Reply

      That first code snippet is just an example of the API call that will be made later, it’s not meant to go into your code.

      Toward the bottom of this post is a link to the source code for this example that you can download and it should work out of the box.

      As a heads up, this method of retrieving twitter timelines via javascript is going to be shut down by twitter very soon and will no longer work.

      See here for a follow up: http://www.itworld.com/unified-communications/343649/death-twitter-api-or-new-beginning

  • Ellis
    on May 3, 2013 Reply

    Around 150 games in total, but that’s relatively small compared to our users. Don’t leave the landscape designing
    and terrain optimization to the last moment. Well, you
    can have that same chess engine on your Android
    mobile phone, courtesy of Droid – Fish.

  • Chris H
    on June 11, 2013 Reply

    Twitter no longer allows unauthorised requests for public tweets.. Any chance we can get an update using oAuth, which is now required?

    Cheers.

  • Tom
    on July 4, 2013 Reply

    Checkout this post if anyone needs a JavaScript twitter feed and guide that authenticates (via PHP) for public timelines
    http://www.webdevdoor.com/javascript-ajax/custom-twitter-feed-integration-jquery/

  • Alamin
    on August 20, 2013 Reply

    I have downloaded the zip file but it is not working. Why?

  • Th@guy
    on January 30, 2014 Reply

    You should maybe update this to reference the new API 1.1 OAuth requirements – Or at least make a statement about the update at the top of the post…

    • Matthew Mombrea
      on January 31, 2014 Reply

      You mean like the very first statement in a huge title tag at the top of the post? Along with the one at the bottom?

Leave a Reply