Advanced Search
Apple Developer Connection
Member Login Log In | Not a Member? Contact ADC
ADC Home > Internet >
Safari Tips for Web Developers
Safari Tips for Web Developers

Web developers have applauded the standards-based approach that Apple has taken in designing Safari, because it means supporting Safari is relatively simple and painless. Most developers are happy to follow the W3C guidelines and have their pages "just work," with no need for browser-specific HTML. However, Safari has the features you'd expect of a modern browser plus a few unique ones; understanding these, as well as a few Safari development tricks, will ensure your web property works exactly the way you and your users expect.

This article takes a look at some of the specifics of how the Safari browser behaves from a development standpoint, valuable tricks that you should be aware of, and specialized behavior. Throughout the article are useful JavaScripts that highlight features of the Safari browser. The source code for these reusable scripts is all contained within the <head> section of this page.

Detecting User Information

Safari identifies itself with the following User-agent string:

Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en-us) AppleWebKit/XX (KHTML, like Gecko) Safari/YY 

where XX is the version of Apple's web technology used by Safari and YY is the version of the Safari application. The AppleWebKit/XX portion identifies the rendering engine and can be used to pinpoint the exact version of Safari that is being used. Here is code to check your user-agent string:

function showUserAgent() {

	var agt=navigator.userAgent; 
	alert ("And your user-agent string is:\n" + agt);

Here is the function displayed in action:

Various aspects of the browser can be retrieved as values of the navigator object. Thus, navigator.appCodeName is "Mozilla," navigator.appName is "Netscape," and navigator.vendor is "Apple Computer, Inc." This script retrieves any of the possible navigator values:

function showNavigatorVariable(theParam) {

	var paramVal = document.getElementById(theParam).value;
	var theNavVariable = "navigator." + paramVal;
	alert("For your browser:\nThe variable [" + paramVal + "] has a value of: " + eval(theNavVariable));

Here it is in action:

Show your browser's value for navigator.

This function detects explicitly whether the user is using a browser based on the Web Kit:

function showIsAppleWebKit() {
	// String found if this is a Web Kit based product
	var kitName = "applewebkit/";
	var tempStr = navigator.userAgent.toLowerCase();
	var pos = tempStr.indexOf(kitName);
	var isAppleWebkit = (pos != -1);

	if (isAppleWebkit) {
		// Grab the version
		var kitVersion = tempStr.substring(pos + kitName.length,tempStr.length);
		kitVersion = kitVersion.substring(0,kitVersion.indexOf(" "));
		alert("Congratulations!\n You are using AppleWebKit version : " + kitVersion);

	} else {
			alert("Bummer\n You are not using AppleWebKit.");

And here it is displayed in action:

To detect a Safari user's preferred language, use the navigator.language property. This code displays the user's language setting in a pop-up window:

function showLanguage(){
  var languageinfo = navigator.language ? navigator.language : navigator.userLanguage; 
  alert ("And the Language is: " + languageinfo);

JavaScript can be used to test a user agent's object capabilities. This Internet Developer Object Detection article explains object detection and how it can be more useful than browser sniffing.

Here is an example of using object detection to test if a browser has support for DHTML:

if (document.getElementById || document.all || document.layers) 
 //browser can handle DHTML 

This checks for the various DOM objects used by various browsers to provide DHTML support—document.getElementById for Safari and other modern browsers; document.all in Internet Explorer 4; and document.layers in Netscape 4.

Cookies, Caching, and Address Bar Icons

Safari (and other browsers) speed up user-end response times by caching static and semi-static content, including cookies. This behavior can be prevented by passing the following HTTP headers to the browser:

Expires: [past date]
Last-Modified: [current date]
Cache-Control: no-store, no-cache, must-revalidate"
Cache-Control: post-check=0, pre-check=0", false
Pragma: no-cache

This can be done with PHP as follows:

<? php
	header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // Date in the past
	header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); // always modified
	header("Cache-Control: no-store, no-cache, must-revalidate"); // HTTP/1.1
	header("Cache-Control: post-check=0, pre-check=0", false);
	header("Pragma: no-cache"); // HTTP/1.0

Cookies can be set and retrieved in Safari (and other browsers) using the following JavaScript snippet:

function testCookies() { 
 var exp = new Date(); 
 exp.setTime(exp.getTime() + 1800000); 
 // first write a test cookie 
 setCookie("cookies", "cookies", exp, false, false, false); 
 if (document.cookie.indexOf('cookies') != -1) { 
   alert("Got Cookies!"); 
 else { 
    alert("No Cookies!"); 
 // now delete the test cookie 
  exp = new Date(); 
  exp.setTime(exp.getTime() - 1800000); 
  setCookie("cookies", "cookies", exp, false, false, false); 

function setCookie(name, value, expires, path, domain, secure) { 
 var curCookie = name + "=" + escape(value) + 
    ((expires) ? "; expires=" + expires.toGMTString() : "") + 
    ((path) ? "; path=" + path : "") + 
    ((domain) ? "; domain=" + domain : "") + 
    ((secure) ? "; secure" : ""); 
 document.cookie = curCookie; 

This button checks your browser for cookies:

Favorite Icon

Safari is compatible with the favorites-icon standard, which displays a 16-by-16-pixel icon in the address bar, like this one:


The icon is supplied by the website. In order to provide a favorites icon to compatible browsers, place the following code in the HEAD area of HTML documents:

	<link rel="icon" href="iconlocation/favicon.ico" type="image/x-icon" /> 
	<link rel="shortcut icon" href="iconlocation/favicon.ico" type="image/x-icon" />

See the article on Hotwired's Webmonkey site: All About the Favorites Icon to learn how to create and display favorites icons.

Java, JavaScript, CSS, and Plugins

Since the release of Java 1.4.1 for Mac OS X, Safari can work with either Java 1.4.1 or 1.3.1. The Java 1.4.1 plugin, JavaPluginCocoa.bundle, is installed to /Library/Internet Plug-Ins when the Java 1.4.1 Update is installed. If this plugin is moved or removed, Safari will automatically revert to using 1.3.1.

All plugins for Safari reside in the /Library/Internet Plug-Ins/ directory. Safari uses Netscape-style plugins, as detailed in Technical Note TN 2020 and Netscape's Plug-in Guide for developers.

Safari offers as complete as possible an implementation of the Cascading Style Sheets standard. There are some lacunae and caveats, detailed in the Internet Developer article, CSS Support in Safari.

In order to debug JavaScript scripts in Safari, it can be helpful to view errors encountered by the scripts in the debugging console. To enable this, execute the following command from the Terminal:

	defaults write IncludeDebugMenu 1 

This causes Safari to include a Debug menu. Selecting "Log JavaScript Exceptions" from this menu allows the errors to be viewed in the Console application.

Miscellaneous Safari Tips

Safari incorporates a built-in pop-up window blocker, which disables pop-up windows triggered by <script> tags, the onLoad handler, the onUnload handler, or timers. This may affect the behavior of websites—when conducting user testing, it is important to test the site with pop-up blocking in both the on and off settings.

Safari's time-out behavior is as follows: the browser will time out if it does not receive a response to an HTTP request or if server data transmission stops for 60 seconds.

Safari follows the HTML specification in rendering Web pages. Pages can be tested for standards compliance, and hence Safari compliance, using the W3C's HTML Validator.

Get information on Apple products.
Visit the Apple Store online or at retail locations.

Copyright © 2003 Apple Computer, Inc.
All rights reserved. | Terms of use | Privacy Notice