Documentation
Hello Dojo!
Welcome to Dojo! In this tutorial, you’ll learn how to load Dojo and begin exploring some of its core functionality. You’ll also learn about Dojo’s AMD-based module architecture, discover how to load additional modules to add extra functionality to your Web site or application, and find out how to get help when things go wrong.
- Difficulty: Beginner
- Dojo Version: 1.8
Getting Started
One of the easiest ways of getting started with Dojo is to leverage Dojo on one of the content delivery networks (CDN). This lets us get off the ground quickly. Using a CDN means your browser will need to connect to the public internet.
This approach allows us to get started quickly using Dojo. For a production application or large scale development, there are other approaches with better performance that we will explain later.
You will need to host all of your examples on a local web server. While browsing files from your local drive can work in certain situations, there are security subtleties that will prevent many things from working. For these examples, you don't need any fancy features in your web server other than the ability to serve files.
This tutorial is really intended for new users of Dojo. If you have used Dojo prior to 1.7 and want to understand what has changed, you might want to start with the Modern Dojo tutorial.
To "bootstrap" Dojo, you will load the dojo/dojo.js file and potentially provide it with some configuration information:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Tutorial: Hello Dojo!</title> </head> <body> <h1 id="greeting">Hello</h1> <!-- load Dojo --> <script src="//ajax.googleapis.com/ajax/libs/dojo/1.8.3/dojo/dojo.js" data-dojo-config="async: true"></script> </body> </html>View Demo
This code makes the Dojo loader available for use by the rest of the page. The Dojo loader is the code that allows you to load other modules.
You might be thinking "hey, they missed the http: from the src attribute. Well, it isn't widely known, but if you drop the protocol from a URL, the browser will assume the protocol that the page was loaded with. This means that your page would work seamlessly if you loaded it via http or https. If you didn't do this, you would likely cause security warnings popping up in your browser in certain situations with https, which isn't a good user experience. If you are running this code on your local machine, be sure you are running from within a local web server, as this won't work if you're using a file: protocol. For many reasons, you should always run Dojo from a web server, even on your local machine.
Another thing you will also notice is the data-dojo-config attribute. This special HTML5 attribute is used to configure Dojo when it is loaded and contains a list of properties that looks and works just like a JavaScript object literal but without the opening and closing curly brackets. In this situation, we are instructing Dojo that we want to operate in an asynchronous mode. This is the new mode introduced in Dojo 1.7 and if you are doing new development, you should use this mode by default. Again, if you are migrating from previous versions of Dojo refer to Modern Dojo tutorial to understand this change better.
You can learn more about configuration in the Configuring Dojo with dojoConfig tutorial.
We have also placed the <script> block in the body of the HTML document. We could place it in the header and things would have worked the same, but when you end up in a situation where your application loads a lot of code, having the <script> blocks in the header can keep the page from rendering while they are being loaded. This adds to the user perception of the application "being slow" and can degrade the user experience, so we will generally be demonstrating loading Dojo at the end of the body of the document.
Starting in Dojo 1.7, Dojo adopted Asynchronous Module Definition (AMD) as the standard for its JavaScript modules. This allows Dojo to not only benefit from performance enhancements that asynchronous module loading can provide, but provided an opportunity to make Dojo more modular than ever, and function without variables in the global namespace. Also, the AMD standard allows Dojo to load other non-Dojo modules as well as Dojo modules to be loaded by other AMD loaders.
In contrast to earlier versions of Dojo, which would automatically load all "base" functionality, when running in asynchronous mode (async: true), Dojo only loads what is required. This makes for applications that perform better. In addition, the modules of Dojo were rewritten to not depend on any more of Dojo and to discretly require in their modules, not expecting any part of Dojo to be "automatically" available except the loader. This is often referred to as "baseless" Dojo.
All tutorials in the Dojo 1.8 tutorial series use baseless Dojo, reaffirming that loading only what you need makes for better, lighter Web applications.
CDN Usage
CDNs are handy. We use them in the tutorial examples, because it means you can copy the code directly and don't have to change anything to have them work for you. They have a few disadvantages though:
- For performance reasons, they are a "built" version of Dojo, which means that each of the modules is minimized and optimized to be sent efficiently over the Internet. This means that when you have an issue, they are more difficult to debug.
- They require your user to have access to the public Internet to use your application. In a lot of cases that may or may not be practical.
- It requires more effort to include your own custom modules.
- If you want to productionize your application, your performance would benefit greatly from a built version of Dojo tailored to your specific application and target browsers, which you can't achieve with a one-size fits all CDN build.
There are a few other tutorials that address these challenges in different ways. Take a look at Creating Builds, Using Custom Modules with a CDN and Configuring Dojo with dojoConfig tutorials for more information.
If you are going to do a significant amount of development, you should download a source distribution and install it on your local web-server. To get the demos working on your local machine, you would want to put the the demo directory that contains your code in the same root directory that contains your Dojo source distribution. You would want something that looks like this:
You would then change the path of your bootstrap loading of Dojo:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Tutorial: Hello Dojo!</title> </head> <body> <h1 id="greeting">Hello</h1> <!-- load Dojo --> <script src="../dojo/dojo.js" data-dojo-config="async: true"></script> </body> </html>
Defining and Requiring Modules
Modules in Dojo are discrete pieces of code that can be individually loaded. They are identified by a string that closely resembles a file path. For example, my/module/id is a Dojo 1.7 and later module identifier (MID). In fact, these identifiers are used to map directly to JavaScript files, which means that a request to load the module "my/module/id" will cause the loader to load whatever module is defined in my/module/id.js.
There are more complex ways of mapping modules to files, but this is all you need for the typical use case with a simple directory structure.
In order to actually require and define modules for use within your application, two global functions are provided by the loader: require(), which is used to load one or more modules, and define(), which is used to define a module. Both of these functions usually take two arguments: a list of MIDs that must be loaded, and a callback function that is executed once those dependencies are available.
This is easy to explain by example. First let us define a module:
// In demo/myModule.js (which means this code defines
// the "demo/myModule" module):
define([
// The dojo/dom module is required by this module, so it goes
// in this list of dependencies.
"dojo/dom"
], function(dom){
// Once all modules in the dependency list have loaded, this
// function is called to define the demo/myModule module.
//
// The dojo/dom module is passed as the first argument to this
// function; additional modules in the dependency list would be
// passed in as subsequent arguments.
var oldText = {};
// This returned object becomes the defined value of this module
return {
setText: function(id, text){
var node = dom.byId(id);
oldText[id] = node.innerHTML;
node.innerHTML = text;
},
restoreText: function(id){
var node = dom.byId(id);
node.innerHTML = oldText[id];
delete oldText[id];
}
};
});
This demo module has a single dependency of its own (dojo/dom) and its value is defined as an object with two methods, setText and restoreText.
Because we are using a CDN for Dojo, but we want to load our custom module locally, we are going to have to modify our configuration for the way we load the module. Otherwise the Dojo loader will assume the module is located on the CDN. This is covered in depth in the Using Custom Modules with a CDN tutorial. For now, just trust that this works:
<script>
// Instead of using data-dojo-config, we’re creating a dojoConfig
// object *before* we load dojo.js; they’re functionally identical,
// it's just easier to read this approach with a larger configuration.
var dojoConfig = {
async: true,
// This code registers the correct location of the "demo"
// package so we can load Dojo from the CDN whilst still
// being able to load local modules
packages: [{
name: "demo",
location: location.pathname.replace(/\/[^/]*$/, '')
}]
};
</script>
If you installed a source distribution on your web server as mentioned above, you will not have to follow this step.
Now that we have created our module and changed the configuration of Dojo, we can load it and do something with it:
// Require the module we just created
require(["demo/myModule"], function(myModule){
// Use our module to change the text in the greeting
myModule.setText("greeting", "Hello Dojo!");
// After a few seconds, restore the text to its original state
setTimeout(function(){
myModule.restoreText("greeting");
}, 3000);
});
View Demo
Using our custom module, this code simply replaces the content of the <h1 id="greeting"> element with “Hello Dojo!”, then restores its original content three seconds later. Note that we aren’t requiring all sub-dependencies in this require call: the loader will automatically load any necessary sub-dependencies until all required code has been loaded.
To learn more about defining and requiring modules in Dojo, check out the Defining Modules tutorial.
Waiting for the DOM
One of the common things that you need to accomplish with web applications is to ensure that the browser's DOM is available before executing code. In Dojo 1.7 and later, when in asynchronous mode, this is accomplished via a special AMD module called a "plugin". Plugins can be required like any other module, but their special functionality is only activated by adding an exclamation point (bang) to the end of the module identifier. In the case of the DOM ready event, Dojo provides the dojo/domReady plugin. Simply include this plugin as a dependency in any require or define call and the callback will not be fired until the DOM is ready:
require(["dojo/dom", "dojo/domReady!"], function(dom){
var greeting = dom.byId("greeting");
greeting.innerHTML += " from Dojo!";
});
View Demo
The example above simply adds some text to the greeting element — something that can only be done reliably once the DOM is loaded. Again, note that the module identifier ends with !; without this, the dojo/domReady module would simply function like any other module.
More information on DOM manipulation functions can be found in the Dojo DOM Functions tutorial.
Adding Visual Effects
Now we can live up our example by adding some animations. One module we can load to add effects to the page is dojo/fx. Let’s add a sliding animation to the greeting with dojo/fx’s slideTo method:
require(["dojo/dom", "dojo/fx", "dojo/domReady!"], function(dom, fx){
// The piece we had before...
var greeting = dom.byId("greeting");
greeting.innerHTML += " from Dojo!";
// ...but now, with an animation!
fx.slideTo({
top: 100,
left: 200,
node: greeting
}).play();
});
View Demo
As you can see, we’ve added one more dependency on dojo/fx, then used that module to play an animation on our greeting element. When new to AMD, you might make the mistake that the array of MIDs (["dojo/dom", "dojo/fx", "dojo/domReady!"]) and the arguments of the callback (function(dom, fx)) are unrelated. However, they are indeed related. When the callback function gets called, the modules are passed in exactly the same order as the array. Because dojo/domReady! doesn't have a meaningful return value, we don't add a return argument for it. Don't make the mistake of thinking that just because you know you don't need a value that somehow JavaScript or Dojo can figure that out automatically. Instead, any modules with a return value that is unused should be at the end of the array. For example, this would be a bad idea:
require(["dojo/dom", "dojo/domReady!", "dojo/fx"], function(dom, fx){
// Not what you wanted, as fx would map to dojo/domReady!, not dojo/fx.
});
More information on effects and animations can be found in the Dojo Effects and Animations tutorials.
Getting Help
Whenever you get confused or run into a tricky problem, you’re not alone! Volunteers are ready to assist via email on the dojo-interest mailing list and via IRC at #dojo on irc.freenode.net. If you think you’ve found an error in our documentation, or read something that’s misleading or confusing, the feedback links at the bottom of all documentation pages can be used to let us know.
If you need urgent or confidential help, or have a problem that can’t be solved by our team of volunteers, commercial Dojo support and training workshops are also available through SitePen.
Where to next?
Getting started with the Dojo Toolkit is as simple as adding a script tag and requiring some modules, but the immense scope and power of Dojo means we’ve barely scratched the surface of what it can do. Depending upon your needs, there are a few different paths through this tutorial series:
- If you have used Dojo before and want to get a better understanding of the World of AMD and "baseless" Dojo, plus understand other concepts that have change, you should take a look at the Modern Dojo tutorial.
- If you are interested in adding some features and effects to an existing static Web page or server-driven Web site, you will want to look next at Using dojo/query, Events with Dojo, and the effects and animations tutorials.
- If you want to add some Ajax to your site, Ajax with Dojo is your ticket.
- If you’re looking to integrate a rich widget library with your Web site or application, take a look at the Creating Template-based Widgets tutorial plus our tutorial series on Dijit widgets.
- If you’re trying to learn more about architecting complex Web applications and leveraging the power of Dojo’s utility functions, head over to the Core Concepts section.
- If your goal is a mobile application, get up and running with Getting Started with dojox/mobile.
No matter your desired outcome, Dojo provides industry-leading open-source tools that can help you get your project done in less time with amazing results. We look forward to seeing what you come up with!

