Posted on by & filed under Content - Highlights and Reviews, Mobile Development.

One of the attractive ideas behind using PhoneGap and HTML combined with CSS and JavaScript is being able to target multiple platforms with one code base. Unfortunately, due to the fact that each platform has its own plugins -– and even its own “cordova.js” file, it isn’t immediately obvious how one can attain a single codebase for all the supported platforms. “Cordova-JS brings a unified Javascript layer to the PhoneGap project making it more consistent and streamlined.”

Note: For this tip, we’re targeting iOS, Android, and Windows Phone 7.5 (Mango). The techniques should extend to any platform you might intend to target.

Multiple Cordova.js files

One of the first hurdles is the Cordova JavaScript library itself. See, this is different for every platform (as of version 1.8.1), and so you can’t simply include one version of it and expect it to work on every platform. This, for instance won’t work:

Yes, it will work on the platform you’re building for initially, but to make it work on another platform, you need the version of the library for the new platform you’re targeting.

Note: This is true if you are building the application yourself. If you are using PhoneGap Build, you don’t upload any “cordova*.js” file at all — PhoneGap Build will place the correct one in the root directory of the project. You can reference it using ; this means only one index.html file should be used. An example of a PhoneGap Build project is at

There are a few ways to deal with this. Personally, the easiest way for me to do it is to use several separate index.html files. While this may initially seem like one would end up with a lot of duplication, it works out pretty well since I build most of my app outside the index files. My index files only contain the bare necessities to start the app –- loading the Cordova library, the initial scripts for our app, and any necessary styles.

My naming convention for these files is as follows:

  • index.html (targeting iOS)
  • index-android.html (targeting Android)
  • index-wp7.html (targeting WP7)

Since we’ll need several “cordova.js” files, I then have a “scripts” directory that contains each version:

I can then reference each platform-specific script in our platform-specific index.html file:

Unfortunately this raises an interesting problem: the Cordova projects are designed to call index.html — not something else. The only fix is to alter each project slightly to accommodate the different index.html files.

    • For iOS:
      • Using the above structure, we don’t actually have to change the iOS project since it will default to using index.html.
    • For Android:

We use the Android Quick Start guide and only need to modify one step. When the guide indicates that this code should be used:

We use this code:

  • For WP7:
    • Edit the “MainPage.xaml” page and alter the StartPageUri property for the PGView. It will default to “/app/www/index.html” – just change it to “/app/www/index-wp7.html”.

Until Cordova unifies the JavaScript libraries (a stated goal), we have to deal with multiple files as a matter of course.

Speaking of Projects…

One of the steps in creating a new project is to include the “www” directory. In a perfect world, we’d be able to have each project pointing at the same “www” directory.

Unfortunately, this isn’t as easy as one might think. While all the IDEs permit a drag-and-drop of the “www” folder into the project structure, they don’t all create links to the original “www” directory. For example, Visual Studio will simply copy the directory. Eclipse, on the other hand, will ask if you want to create a virtual folder, which seems tempting, except that the deployment scripts don’t properly handle this, and so you’ll end up with missing files on the device.

XCode is the only IDE that permits a direct link to the “www” directory. When dragging the directory in, you’re presented with a dialog that asks how you’d like to reference the directory. Change it to look like the image below, and you’ll have a proper link.

XCode is smart enough to realize that even though your “www” folder may be anywhere on your computer that it should be deployed relative to your app’s directory on the device.

So what do we do with Eclipse and Visual Studio? There are two methods – one a bit more tricky than the other, so it depends on your preference.

The first method is simply to do what the IDEs want: make a duplicate “www” folder. The problem is then merging any changes you might make back into your primary “www” folder. The method works, but it’s on you to ensure that the two are kept in sync.

The second method is to use symbolic linking. This has to be done outside the IDE, since they don’t natively create a symbolic link. Open up your command prompt and navigate to the level directly above where you want your “www” directory to be created:

For Mac OS X/Linux:

For Windows:

You’ll probably have to refresh your IDE after this to make sure it picks up all the new files. If it doesn’t – just drag the “www” folder in to the IDE’s project structure – this will pick up the changes.

The benefit of using a symbolic link is that any changes you make while in the IDE will be propagated out to your primary “www” directory. The unfortunate side effect is that versioning tools such as Git don’t generally handle these very well – they may ignore the symbolic link entirely, or they may duplicate the structure.

Handling plugins

Every plugin will come with a JavaScript file that you have to attach to your project. This script must be placed somewhere in your “www” folder. Since a plugin may share the same name across platforms, I like to put it in the following structure:

Then any plugin scripts will go in their respective platform’s directory. To include them, just update the platform-specific index.html file.

When using them, though, you need to know which plugin you’re talking to — especially if they have the same name across all the platforms (like ChildBrowser). To do this, use the device.platform property:

Note: The default section above is where I like to do my iOS-specific work. This is because device.platform can return many different values for iOS including iPhone, iPad, iPhone Simulator, and iPad Simulator. Rather than have a case for each, I just use default. You can have a case for each, though, if you’d like. In our second tip, we’ll write a function that compresses these down to “iOS”.

Differences in XMLHttpRequest processing

It is often a requirement that your script will need to call upon XMLHttpRequest to load in local resources. There’s a couple of subtle things you need to watch out for when you do this, though, or you’re likely to pull your hair out when things don’t quite work right.

The typical script looks akin to this:

There’s two problems with this code: one, on certain platforms, it will fail because the status code won’t be 200 on success, but zero instead! So we need to add a check like this:

Secondly, for WP7.x, local files need be referenced relative to the /app/www directory, so you need to take care of that like this:

Really Important Note: WP7 can really be a stinker sometimes. If you use XHR to synchronously load files (by setting the third parameter of to false), you’ll end up with some serious instability. Sometimes the files will load; sometimes they won’t. So the natural inclination is to set this back to true – which is right. Unfortunately this means you’ll have to chain all your requests to XHR because for some reason the results will often contain data from the wrong file if there is more than one XHR going on at once. So, while Android and iOS will handle both synchronous and asynchronous XHR just fine, WP7 requires that you use chained asynchronous XHR. Or synchronous asynchronous XHR if you like. Yes, it’s really that painful. If you don’t chain your XHRs, you’ll end up pulling out all your hair wondering why things aren’t working (or why you’re getting the wrong file contents). If you want an example, look at our sample App – it has to chain its XHR for this very reason.

Speaking of WP7

Don’t even bother targeting WP7.0

Oh, if only the world were full of proper mobile browsers. On both iOS and Android we have reasonably good implementations of WebKit (although for Android 2.x this is somewhat debatable), but on WP7 we have a browser engine based around the Trident engine. Guess what – we’re now back in the realm of dealing with Internet Explorer. *sigh*

WP7 before the Mango release used a browser engine based around a hybrid IE7/8. There’s a lot of things wrong with this browser, including its lack of a lot of standards we take for granted today. Believe me when this particular incarnation of IE would be better off forgotten – it’s really that bad.

WP7.5 (Mango) is much better. It is based around IE9, so there’s decent support for the various standards used in creating a good mobile app, minus a few notable features: 3D transforms and animations. That aside, it is possible to create passable apps on WP7.5, though they won’t feel quite “native” as the browser is still quite hamstrung. While we’re on the subject:
WP7.5 and the lack of Touch events

There’s one more mind-blowing feature lacking in WP7.5: there’s no touch event handling. That’s right, touchstart, touchmove, and touchend aren’t supported. Instead mousedown, mousemove, and mouseup are the equivalents which means there’s no support for multi-touch at all. But it also means you have to attach your event listeners to two different possible events: touch events for WebKit browsers and mouse events for IE.

You can do this quite easily like this:

Better yet, you could create a function to handle the above for you so as to avoid some of the duplication.
Wrapping Up

Needless to say, supporting a single code base isn’t easy, nor is it terribly pretty. But it is possible to do successfully, and after some time, it’ll be like second nature.

In our next tip, we’ll continue this train of thought visually: how to change the look and feel of our app based on the platform it is running on.

Safari Books Online has the content you need

Check out these Phonegap books available from Safari Books Online:

20 Recipes for Programming PhoneGap explores many common features of mobile development and how they are accomplished with PhoneGap. This will include GPS location, maps, media, accelerometer, and much more. PhoneGap is a library that allows developers to interface directly with a mobile device through the use of its Javascript libraries. With the multitude of mobile platforms it is very difficult and expensive to create multiple applications in Java, Objective-C, or other native languages. Through the PhoneGap library, most web developers can convert their existing knowledge of HTML, CSS, and Javascript into mobile phone applications with very little effort.
PhoneGap Beginner’s Guide shows you how to use the PhoneGap mobile development framework to target multiple mobile platforms: iOS, Android, BlackBerry, and more with a single application. With PhoneGap, you can use existing web development skills, instead of learning a new environment for every platform on the market.
Using HTML, CSS, and Javascript, PhoneGap allows you to jump into the mobile world and develop apps for iPhone, Android, and the BlackBerry, and Beginning PhoneGap will help show you how to best take advantage of PhoneGap.
Beginning PhoneGap: Mobile Web Framework for JavaScript and HTML5 is a definitive, one-of-a-kind book that teaches the fundamentals and strategies behind cross-platform mobile application development. Instead of learning languages like Objective-C, focus on building apps from day one for Android, iOS, Blackberry, WebOS and Symbian—without the complexities of these platforms.
Head First Mobile Web shows how to use the web tech- nology you’re already familiar with to make sites and apps that work on any device of any size. Put your JavaScript, CSS media query, and HTML5 skills to work, and then optimize your site to perform its best in the demanding mobile market.
Build Mobile Websites and Apps for Smart Devices provides practical, up to date information on all aspects of Mobile Web Development, using an easy to follow, tutorial style, with step-by-step instructions and clear examples.

About this author

Kerri Shotts has been programming since she learned BASIC on her Commodore 64. She earned her degree in Computer Science and has worked as a Test Engineer and Database Administrator. Now a Technology Consultant, she helps her clients with custom websites, apps (desktop and mobile), and more. When not at the computer, she enjoys photography and taking care of her aquariums.

Tags: android, Cordova, Eclipse, iOS, Javascript, Mango, PhoneGap, Visual Studio, Xcode,

3 Responses to “Searching for a Single Codebase with PhoneGap”

  1. abhishek

    hi kerri
    nice article.
    But I wanted to ask more about the plugins??
    Question is where will we put the plugin codes like [Android Intent code java files]
    or ios .m .h files and how will we use phonegap build to utilise these plugins..

    Thanks in advance…


  1.  MCRooster: A PhoneGap Application with a Single Codebase | Safari Books Online's Official Blog