Quick Tip: An Introduction to Sammy.js

Quick Tip: An Introduction to Sammy.js

Tutorial Details
  • Program: Sammy.js
  • Version: 0.5.4
  • Difficulty: Intermediate
  • Estimated Completion Time: 15 Minutes

You’ve been seeing it for a while now with Google’s Reader, Gmail, and most recently, on Facebook. Probably, you, too, would like to write RESTful evented JavaScript applications. Well, fellow developers, meet Sammy.js, a tiny JavaScript framework built on top of jQuery. Sammy utilizes the URL hash (#) to allow you to create single page AJAX applications that respond to your browser’s back button. Interested?

In this article, I’ll be providing a short overview of the framework, and then a brief demonstration of what it’s like working with Sammy.js, with the hope of enticing you enough to consider it for your projects.


Setting the Stage

“Sammy.js is light both in size (<20kb) and footprint. Pull it into your already started applications.”

Sammy.js is being put together by Aaron Quint, a web developer out of Brooklyn, NY. Its API is modeled on the popular ruby framework, Sinatra, and is great for both simple and complex applications. It’s easy to get into, and can be pulled into your existing projects. It’s not an all or nothing proposition; so let’s take a look.

Sammy.js allows you to write single page apps, much like Gmail. You can maintain the state of your app with the url, without having to refresh or change the page. There are other MVC JavaScript frameworks, like SproutCore, which tend to be all encompassing. But with Sammy, you have a light (~20kb) framework, capable of invoking several instances simultaneously (ie. running multiple apps in the same document).


Opening Act

Installing Sammy.js is pretty straightforward. Head on over to the download page, grab a copy and move, sammy-0.5.4.min.js to where you store your project’s libraries (typically /js for me). For the purpose of this article, I will be using version 0.5.4, but you may be inclined to try sammy-latest.min.js. You’ll also need a copy of jQuery, at least v. 1.4.1. As with most jQuery plugins, order is important: jQuery, before Sammy.js, before your JavaScript. I tend to put my JavaScript at the bottom of the page, because it blocks other items from loading in parallel, giving the impression of a slower loading page. So far we have:

    <!DOCTYPE html>
    <html lang="en">
    <head>
    	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    	<title>Sammy.js Example</title>
    </head>
    <body>
    
        <div id="content"></div>
    
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
        <script type="text/javascript" src="js/sammy-0.5.4.min.js"></script>
        <script type="text/javascript">
        
            // your script goes here
            
        </script>
        
    </body>
    </html>

Now to start coding our app. To keep things simple, I’m working inline, which isn’t the best practice. Adding a Sammy.js application is as simple as assigning it to a variable, which I’m calling ratPack. On our page we’ve defined a div with the id “content” upon which our application will be acting. We indicate this as follows:


    var ratPack = $.sammy(function() {

        this.element_selector = '#content';
        
        // routes will go here

    });
    

The importance of the element selector is that we can have multiple instances of Sammy.js running in our document, affecting different elements.


Main Attraction

Sammy.js uses the path, as defined in the URL hash, and the common HTTP methods (get, post, put, delete) to determine a callback function to invoke. These are typically known as “routes”. Some examples from around the web would be:

As an example, we’ll sketch up a mailbox application. Let’s first setup the default route of our app, which will land on #/inbox.

    this.get('#/inbox', function(context) {
        context.app.swap('');
        context.$element().append('<h1>inbox</h1>');
    });

Here, you can make the callback function do whatever you’d like. Since I’m displaying an inbox, I’d probably want to make an ajax call and retrieve a list of messages. However, for the sake of simplicity, I’m just going to return a h1 tag. The context.app.swap('') tells Sammy to replace what’s in my content div, rather than just appending to it.

In order to get this working in the browser, we’ll want to run the app using jQuery’s document ready function and pass it to our starting URL, as defined in the above route.

    
    $(function() {
      ratPack.run('#/inbox');
    });
    

And that’s it. We should now be able to load our document in a browser, the app should launch and navigate us to our inbox.

Next, we can create another route to handle labeled messages:

    
    this.get('#/label/:name', function(context) {
        context.app.swap('');
        context.$element().append('<h1>' + this.params['name'] + '</h1>'); 
    });

Sammy uses the colon var syntax (:var) to return parameters for us to filter our messages. Again, I’m just displaying the name of the label.

To this point, we’ve only been using the “get” HTTP method. Say we were to create a form and route it to #/compose:

    this.get('#/compose', function(context) {
        context.app.swap('');
        context.$element().append('<h1>say hello to?</h1>'
          + '<form action="#/compose" method="post">'
          + '<input type="text" name="to" />'
          + '<input type="submit" name="submit" />'
          + '</form>'); 
    });

Now we can setup a route to accept the posted data and have Sammy parse it for us.

this.post('#/compose', function(context) {
    context.app.swap('');
    var to = this.params['to'];
    context.$element().append('<h1>hi ' + to + '</h1>');
});

That’s the basics. A simple API, powerful enough for projects both big and small. If you are following along with the code, we can add some navigation for ease of clicking.

    <div id="nav">
        <ul>
            <li><a href="#/inbox">inbox</a></li>
            <li><a href="#/compose">compose</a></li>
            <li><a href="#/label/drafts">drafts</a></li>
        </ul>
    </div>

Encore

Of course, Sammy.js has a lot more to offer than simply defining routes in the app. More advanced users can explore custom events and namespaces, for event-driven applications. Aaron is trying to keep the core of Sammy.js as tight as possible, but it also comes with a lot of plugins. There’s a title plugin, that allows you to easily set the document’s title for different routes. There are several templating systems, including haml and mustache. There’s a nice-looking form builder and Sammy.Store, “an abstract adapter class that wraps the multitude of in browser data storage into a single common set of methods for storing and retreiving data.”

I hope you’ve enjoyed this quick look at Sammy.js and are ready to consider using it in your applications. Let’s hear your thoughts on Sammy.js in the comments!

Tags: jQuery
Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • http://yamilurbina.com yamilurbina

    Sounds cool. I’m trying it as I write this. The fact that uses URL’s atracts me the most.

  • Dan

    This looks nice for small widgets.

  • Sahan

    User-friendly ajax :)

  • http://www.aediscreative.com Christopher

    freakin sweet! Damn its been a good day on nettuts.

  • Zlatan Halilovic

    I have to agree on that one :)

  • Andy King

    Simply awesome. Search-engine-indexable, bookmarkable, back-button friendly AJAX in a lightweight script. Joyous! Thanks to Aaron Quint for developing it, and to Arlo Breault for sharing this.

    • http://hosting4developers.com Jonas

      Sammy.js and similar scripts do not make your pages search-engine-indexable, so they’re mostly suited for apps that you log in to (because search engines wouldn’t normally index those pages anyway).

      • http://www.kirkbushell.com Kirk Bushell

        Jonas, that’s not entirely correct. If you follow Google’s guides on how to index state-based web pages, you can have all your content indexed.

  • elkaz

    I think Hotmail needs to get on board this bandwagon already.

  • http://www.satya-weblog.com Satya Prakash

    I read long back that # is a good tool in url to use it for preserving state and tracking pages. but reading about it will be a good journey. I was not aware of that sammy is in use on so many sites. even i was not aware of sammy. oh! need to get good knowledge of JQuery. I know only basic of it.

    • http://thoughtherder.com/ Arlo Breault
      Author

      Just to clarify, Sammy isn’t being used by Google, or Facebook. (At least not that I’m aware of.) Those were just example of where the pattern is appearing.

      • http://www.satya-weblog.com Satya Prakash

        Thanks for clarification

  • http://hyperlexic.com hyperlexic

    greatest article photo ever.

    • http://www.vijayjoshi.name/ Vijay

      Yours too ;)

    • http://thoughtherder.com/ Arlo Breault
      Author

      :P

  • http://twitter.com/johanbrook Johan

    Nice! Came like a letter in the mail. Love the back button support, and the fact that it’s built upon jQuery. Thanks!

  • http://www.codeforest.net Codeforest

    Nice technique, Back button support is really sweet . Thanks for sharing

  • http://psdho.me PSDhome – Everyday free PHOTOSHOP files

    Very nice post. Thanks you so much.

  • Stefan

    Cool but nothing new, since SWFAddress have done this for years. But Sammy might be better and faster because it’s build on top of jQuery?

  • http://www.art-forums.net Rory C

    I’d read a few articles on how to do this from scratch, but had no idea there was a framework already. Great trick, and one that I’ll definitely use. Thanks!

  • w1sh

    Looks pretty cool. Does anyone know of any Sammy.js demos out there so I can see some more things it brings to the table?

  • http://jens.scherbl.net Jens Scherbl

    Thanks for sharing.

    While I’m generally not a big fan of unnecessary overuse of Ajax all over the place (see Facebook for a pretty good example how NOT to use Ajax), this might actually come in handy in some very specific situations.

    I also recommend reading “The Overuse of Ajax and How to be a good Ajax developer” by Cory Mawhorter:

    http://www.mawhorter.net/web-development/the-overuse-of-ajax-and-how-to-be-a-good-ajax-developer

    • http://twitter.com/mightystassen The Mighty Stassen

      Maybe if you’re living in 1995. Ajax and Websockets are the future.

  • http://www.lehisanchez.com Lehi Sanchez

    I’ve been looking for a js-based solution for implementing routes. I’ll be looking forward to testing this with my iPad Web App. Thanks for posting!

  • http://mileonemedia.com Joe Cianflone

    Perfect timing! Yesterday I was talking about implementing this on project and today I get a nice tutorial from nettuts!

  • http://www.shiftedwork.de/blog/ Daniel S

    WAIT! That sounds interesting – but your User will see NOTHING if he disables JavaScript – and thats a big disadvantage to usability. We need to develop a workaround for the guys who switched of javascript, man!

    Greetings from Germany,

    Daniel

  • Alexander

    What about an analog for mootools? Is there smth?

  • Jamal Mohamed

    Nice script. It sound cool and I’m gonna bookmark in case I need some functionality like that in the future.

    The name is ‘orrible though. Wasn’t it Samy’s script that went from profile to profile in MySpace several years ago, that added “but most of all, Samy is my hero” statement in every profile it went trough… A villain’s namesake indeed.

  • VanThien

    Thanks it. This can help me.

  • http://adrusi.com adrian

    there was a post in jquery for designers not long ago that promoted an virtually identical plugin BBQ (http://benalman.com/projects/jquery-bbq-plugin/) and chris posted something on css tricks on how to do it yourself

  • http://twitter.com/xRommelx xRommelx

    this is really awesome!

  • Xarren

    Anyone tried this with CodeIgniter? How does it work together with CI segmented links? I’m going to try it out once I’ve finished my current projects, however I’m a bit worried that CI might treat the extra segment as an argument.

  • http://haskovo.co Хасково

    Thanks :) It was very useful for me :)

  • http://www.websitetemplates.bz Dima

    To my mind, Xarren is right, tough there is nothing to worry about

    Wonderful post !

  • http://myfacefriends.com Jehnee

    very nice thanks!

  • http://hosting4developers.com Jonas

    Good idea, but keep in mind that this does NOT make your Ajax-driven page search engine friendly. It does, however, ensure that the states of your app can be bookmarked.

  • http://www.dnaurex.co.cc Aurelio Santos
    • http://hosting4developers.com Jonas

      As far as I can see, search engines still cannot read JavaScript, so if you want to use the hash mark, you still have to provide the content to the search engines as HTML, not JavaScript. That’s more complicated than what’s been shown above.

  • http://www.blagoevgrad.net Blagoevgrad

    Great information! Thanks for posting

  • Ed

    Xarren,

    Yes this does work with codeigniter.

    it works pretty much the same way as described in this tutorial.

    I love sammy.js so I’m glad that it does work with codeigniter.

  • alex

    how i can load another file by sammerjs?

    for exemple, in php i write:

    ps. I just start styding JS

    thans, wmag