Backbone.js Routing Basics

Written by Backbone Tutorials Team

Last updated: June 2026 · 9 min read

A single page app has no page reloads, yet users still expect the back button to work and a link to a specific item to reopen that item. Routing is what delivers both. Backbone's Router maps pieces of the URL to functions in your code, turning the address bar into another input that drives the app, right alongside clicks and model changes.

This guide builds on what a router is and goes a layer deeper into how routing actually runs: the routes hash, parameters, the history engine that watches the URL, and the choice between hash and real paths. It is the final piece of the Foundations cluster.

How a URL becomes a view The address bar feeds Backbone.history, which matches a route in the routes hash and calls a handler that renders a view. Address bar/users/42 Backbone.historywatches URL routes hashusers/:id handlerrender match the fragment → call showUser(42)
The URL flows into Backbone.history, which matches a pattern in the routes hash and calls the handler that renders the right view.

What the Router actually does

A Router is a lookup table from URL fragments to functions. You list patterns in a routes hash, pair each with a method name, and Backbone calls the matching method whenever the URL changes to fit. That is the entire idea; everything else is detail on top of it.

The routes hash

var AppRouter = Backbone.Router.extend({
  routes: {
    '':            'home',
    'users/:id':   'showUser',
    'search/*query': 'search'
  },
  home:     function ()      { /* render home */ },
  showUser: function (id)    { /* render user id */ },
  search:   function (query) { /* render results */ }
});

Read top to bottom, the hash says: an empty fragment runs home, users/ followed by a value runs showUser with that value, and anything under search/ runs search with the rest. The patterns are matched in order, so list the most specific ones first.

Route parameters and splats

Routes are rarely fixed strings; they carry data. Backbone has two ways to capture it, and the difference is how much they grab.

Named parameters versus splats

A named parameter, written with a leading colon as in :id, matches a single segment and stops at the next slash. A splat, written with an asterisk as in *query, is greedy and swallows everything to the end of the URL, slashes included. Wrapping a part in parentheses makes it optional. Use a parameter for one value like a record id, and a splat for an open-ended tail like a search string or a file path.

Starting Backbone.history

Defining routes is not enough; something has to watch the URL and fire them. That something is Backbone.history, and your app does nothing route-related until you start it.

Hash fragments versus pushState

new AppRouter();
Backbone.history.start({ pushState: true });

Calling start dispatches the route for whatever URL is already loaded and then listens for changes. Without the option, Backbone uses hash URLs like /#users/42, which work anywhere. With pushState, it uses clean paths like /users/42, which look better but come with a server requirement covered at the end.

Links handle most navigation, but you often need to move the user yourself, after a save or a login. navigate updates the address bar from code, and one option decides whether it also runs the route.

trigger: true versus a silent URL update

// update the URL AND run showUser:
router.navigate('users/42', { trigger: true });

// update the URL only, run nothing:
router.navigate('users/42');

Pass trigger: true when the destination should actually load; leave it off when you only want the URL to reflect a state you have already rendered. That second form is how you keep a shareable link in sync with, say, an open tab without re-rendering it.

Routing as the app's state coordinator

In a structured app, the Router sits near the top and decides which screen is active, which makes it tempting to pile logic into route handlers. Resist that. A route handler should pick the view and hand off, not contain the feature.

Keep routes thin

Let each handler create or reveal the right view and then get out of the way, delegating the real work to the views and models from the application structure guide. Thin routes stay readable as the app grows, and they keep the URL-to-screen mapping easy to see at a glance instead of buried in business logic.

pushState, the server, and deep links

Clean URLs carry one obligation. With hash routing the server only ever sees the part before the hash, so it always serves your app. With pushState, a refresh on /users/42 sends that whole path to the server, which must be told to return the app rather than a missing page.

Why pushState needs server support

Configure the server to serve your single index.html for any client route, and deep links and refreshes work again. This is also where routing meets search: client-rendered paths need crawlers to reach the same content, the subject of SEO for single page apps. Get the server fallback and the rendering right, and a Backbone app is as linkable and crawlable as any traditional site.

That completes the Backbone Foundations: the four core objects, the events that connect them, views and their lifecycle, templates, sync, application structure, data flow, and now routing. With these in hand, you are ready for the wider Backbone.js guide and the architecture topics beyond it.

Frequently Asked Questions

What does Backbone.history.start() do?

It begins monitoring the URL and dispatches the route that matches the current address. Until you call it, no route ever fires. Passing the pushState option tells Backbone to use real paths through the History API instead of hash fragments.

What is the difference between hash and pushState routing?

Hash routing keeps state after a hash mark, like /#users/42, and works on any static host with no server setup. pushState routing uses clean paths, like /users/42, but the server must return the app for those paths so a refresh or deep link still loads.

How do I change the URL from code in Backbone?

Call router.navigate with the path. Pass the trigger option as true to also run the matching route function, or leave it off to update the address bar silently, which is useful for reflecting state without re-running a handler.

Is Backbone routing good for SEO?

Client-rendered routes need the same crawl-and-render care as any single page app. Serve real URLs with pushState and make sure each route's content is available to crawlers, as covered in the SEO for single page apps tutorial.

Read next: back to the Foundations hub, or step up to the full Backbone.js guide now that the foundations are complete.

Foundations complete, what's next?

You have the core. The complete guide shows how Models, Views, Routers, and Collections work together in one application.

Explore the Backbone Guide →