diff --git a/include/ajax.tips.php b/include/ajax.tips.php
new file mode 100644
index 0000000000000000000000000000000000000000..b3281d75f9a81a0e979157b7f8a4c95725305f5c
--- /dev/null
+++ b/include/ajax.tips.php
@@ -0,0 +1,38 @@
+<?php
+/*********************************************************************
+    ajax.tips.php
+
+    AJAX interface for help popovers. Initially written to allow
+    translations of the installer help popups
+
+    Peter Rotich <peter@osticket.com>
+    Jared Hancock <jared@osticket.com>
+    Copyright (c)  2006-2013 osTicket
+    http://www.osticket.com
+
+    Released under the GNU General Public License WITHOUT ANY WARRANTY.
+    See LICENSE.TXT for details.
+
+    vim: expandtab sw=4 ts=4 sts=4:
+**********************************************************************/
+if(!defined('INCLUDE_DIR')) die('!');
+
+require_once(INCLUDE_DIR.'class.i18n.php');
+
+class HelpTipAjaxAPI extends AjaxController {
+    function getTipsJson($namespace, $lang='en_US') {
+        $i18n = new Internationalization($lang);
+        $tips = $i18n->getTemplate("help/tips/$namespace.yaml");
+
+        if (!$tips || !($data = $tips->getData()))
+            Http::response(404, 'Help content not available');
+
+        return $this->json_encode($data);
+    }
+
+    function getTipsJsonForLang($lang, $namespace) {
+        return $this->getTipJson($namespace, $lang);
+    }
+}
+
+?>
diff --git a/include/i18n/en_US/help/tips/install.yaml b/include/i18n/en_US/help/tips/install.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..2cb86b36dfeee5b7a282c2e797f4fd992fa06234
--- /dev/null
+++ b/include/i18n/en_US/help/tips/install.yaml
@@ -0,0 +1,85 @@
+#
+# Help popup items for the installer
+#
+# Fields:
+# title - Shown in bold at the top of the popover window
+# content - The body of the help popover
+#
+# The key names such as 'helpdesk_name' should not be translated as they
+# must match the HTML #ids put into the page template.
+#
+---
+helpdesk_name:
+    title: Helpdesk Name
+    content: |
+        <p>The name of your support system e.g [Company Name] Support</p>
+
+system_email:
+    title: Default System Email
+    content: |
+        <p>Default email address e.g support@yourcompany.com - you can add
+        more later!</p>
+
+first_name:
+    title: First Name
+    content: |
+        <p>Admin's first name</p>
+
+last_name:
+    title: Last Name
+    content: |
+        <p>Admin's last name</p>
+
+email:
+    title: Email Address
+    content: |
+        <p>Admin's personal email address. Must be different from system's
+        default email.</p>
+
+username:
+    title: Username
+    content: |
+        <p>Admin's login name. Must be at least three (3) characters.</p>
+
+password:
+    title: Password
+    content: |
+        <p>Admin's password.  Must be five (5) characters or more.</p>
+
+password2:
+    title: Confirm Password
+    content: |
+        <p>Retype admin's password. Must match.</p>
+
+db_prefix:
+    title: MySQL Table Prefix
+    content: |
+        <p>osTicket requires table prefix in order to avoid possible table
+        conflicts in a shared database.</p>
+
+db_host:
+    title: MySQL Hostname
+    content: |
+        <p>
+        Most hosts use 'localhost' for local database hostname. Check with
+        your host if localhost fails.
+        </p>
+        <p>
+        Default port set in php.ini is assumed. A non-standard port number
+        can be specified as <code>hostname:port</code>
+        </p>
+
+db_schema:
+    title: MySQL Database
+    content: |
+        <p>Name of the database osTicket will use.</p>
+
+db_user:
+    title: MySQL Username
+    content: |
+        <p>The MySQL user must have full rights to the database.</p>
+
+db_password:
+    title: MySQL Password
+    content: |
+        <p>MySQL password associated with above user.</p>
diff --git a/setup/ajax.php b/setup/ajax.php
new file mode 100644
index 0000000000000000000000000000000000000000..b33f3310f31cfa1779486925bec26ea8cd04fc5e
--- /dev/null
+++ b/setup/ajax.php
@@ -0,0 +1,32 @@
+<?php
+/*********************************************************************
+    ajax.php
+
+    Ajax utils for the installer interface.
+
+    Peter Rotich <peter@osticket.com>
+    Copyright (c)  2006-2013 osTicket
+    http://www.osticket.com
+
+    Released under the GNU General Public License WITHOUT ANY WARRANTY.
+    See LICENSE.TXT for details.
+
+    vim: expandtab sw=4 ts=4 sts=4:
+**********************************************************************/
+
+require('setup.inc.php');
+
+if(!defined('INCLUDE_DIR'))
+    Http::response(500, 'Server configuration error');
+require_once INCLUDE_DIR.'/class.dispatcher.php';
+require_once INCLUDE_DIR.'/class.ajax.php';
+
+$dispatcher = patterns('',
+    url('^/help/', patterns('ajax.tips.php:HelpTipAjaxAPI',
+        url_get('tips/(?P<namespace>[\w_]+)$', 'getTipsJson'),
+        url_get('(?P<lang>\w{2}_\w{2})?/tips/(?P<namespace>[\w_]+)$', 'getTipsForLangJson')
+    ))
+);
+print $dispatcher->resolve(Osticket::get_path_info());
+?>
+
diff --git a/setup/inc/install.inc.php b/setup/inc/install.inc.php
index cb5f2d82bfd15b2fcb9e95087b443844d0f3a02a..c9f16384398a75e5d6c919b2fdf08be948ff7189 100644
--- a/setup/inc/install.inc.php
+++ b/setup/inc/install.inc.php
@@ -17,13 +17,13 @@ $info=($_POST && $errors)?Format::htmlchars($_POST):array('prefix'=>'ost_','dbho
                 <div class="row">
                     <label>Helpdesk Name:</label>
                     <input type="text" name="name" size="45" tabindex="1" value="<?php echo $info['name']; ?>">
-                    <a class="tip" href="#t1">?</a>
+                    <a class="tip" href="#helpdesk_name">?</a>
                     <font class="error"><?php echo $errors['name']; ?></font>
                 </div>
                 <div class="row">
                     <label>Default Email:</label>
                     <input type="text" name="email" size="45" tabindex="2" value="<?php echo $info['email']; ?>">
-                    <a class="tip" href="#t2">?</a>
+                    <a class="tip" href="#system_email">?</a>
                     <font class="error"><?php echo $errors['email']; ?></font>
                 </div>
 
@@ -32,37 +32,37 @@ $info=($_POST && $errors)?Format::htmlchars($_POST):array('prefix'=>'ost_','dbho
                 <div class="row">
                     <label>First Name:</label>
                     <input type="text" name="fname" size="45" tabindex="3" value="<?php echo $info['fname']; ?>">
-                    <a class="tip" href="#t3">?</a>
+                    <a class="tip" href="#first_name">?</a>
                     <font class="error"><?php echo $errors['fname']; ?></font>
                 </div>
                 <div class="row">
                     <label>Last Name:</label>
                     <input type="text" name="lname" size="45" tabindex="4" value="<?php echo $info['lname']; ?>">
-                    <a class="tip" href="#t4">?</a>
+                    <a class="tip" href="#last_name">?</a>
                     <font class="error"><?php echo $errors['lname']; ?></font>
                 </div>
                 <div class="row">
                     <label>Email Address:</label>
                     <input type="text" name="admin_email" size="45" tabindex="5" value="<?php echo $info['admin_email']; ?>">
-                    <a class="tip" href="#t5">?</a>
+                    <a class="tip" href="#email">?</a>
                     <font class="error"><?php echo $errors['admin_email']; ?></font>
                 </div>
                 <div class="row">
                     <label>Username:</label>
                     <input type="text" name="username" size="45" tabindex="6" value="<?php echo $info['username']; ?>" autocomplete="off">
-                    <a class="tip" href="#t6">?</a>
+                    <a class="tip" href="#username">?</a>
                     <font class="error"><?php echo $errors['username']; ?></font>
                 </div>
                 <div class="row">
                     <label> Password:</label>
                     <input type="password" name="passwd" size="45" tabindex="7" value="<?php echo $info['passwd']; ?>" autocomplete="off">
-                    <a class="tip" href="#t7">?</a>
+                    <a class="tip" href="#password">?</a>
                     <font class="error"><?php echo $errors['passwd']; ?></font>
                 </div>
                 <div class="row">
                     <label>Retype Password:</label>
                     <input type="password" name="passwd2" size="45" tabindex="8" value="<?php echo $info['passwd2']; ?>">
-                    <a class="tip" href="#t8">?</a>
+                    <a class="tip" href="#password2">?</a>
                     <font class="error"><?php echo $errors['passwd2']; ?></font>
                 </div>
 
@@ -71,31 +71,31 @@ $info=($_POST && $errors)?Format::htmlchars($_POST):array('prefix'=>'ost_','dbho
                 <div class="row">
                     <label>MySQL Table Prefix:</label>
                     <input type="text" name="prefix" size="45" tabindex="9" value="<?php echo $info['prefix']; ?>">
-                    <a class="tip" href="#t9">?</a>
+                    <a class="tip" href="#db_prefix">?</a>
                     <font class="error"><?php echo $errors['prefix']; ?></font>
                 </div>
                 <div class="row">
                     <label>MySQL Hostname:</label>
                     <input type="text" name="dbhost" size="45" tabindex="10" value="<?php echo $info['dbhost']; ?>">
-                    <a class="tip" href="#t10">?</a>
+                    <a class="tip" href="#db_host">?</a>
                     <font class="error"><?php echo $errors['dbhost']; ?></font>
                 </div>
                 <div class="row">
                     <label>MySQL Database:</label>
                     <input type="text" name="dbname" size="45" tabindex="11" value="<?php echo $info['dbname']; ?>">
-                    <a class="tip" href="#t11">?</a>
+                    <a class="tip" href="#db_schema">?</a>
                     <font class="error"><?php echo $errors['dbname']; ?></font>
                 </div>
                 <div class="row">
                     <label>MySQL Username:</label>
                     <input type="text" name="dbuser" size="45" tabindex="12" value="<?php echo $info['dbuser']; ?>">
-                    <a class="tip" href="#t12">?</a>
+                    <a class="tip" href="#db_user">?</a>
                     <font class="error"><?php echo $errors['dbuser']; ?></font>
                 </div>
                 <div class="row">
                     <label>MySQL Password:</label>
                     <input type="password" name="dbpass" size="45" tabindex="13" value="<?php echo $info['dbpass']; ?>">
-                    <a class="tip" href="#t13">?</a>
+                    <a class="tip" href="#db_password">?</a>
                     <font class="error"><?php echo $errors['dbpass']; ?></font>
                 </div>
                 <br>
diff --git a/setup/js/tips.js b/setup/js/tips.js
index 76c20421a28c9301a92497a778de881e1e4f91fe..9fd2007e5a67cd2e98b85b3ef1df81deb092dfb4 100644
--- a/setup/js/tips.js
+++ b/setup/js/tips.js
@@ -1,46 +1,77 @@
 jQuery(function($) {
-    var tips = $('.tip');
-    for(i=0;i<tips.length;i++) {
-        tips[i].rel = 'tip-' + i;
-    }
+    getHelpTips = (function() {
+        var dfd = $.Deferred();
+        return function() {
+            if (dfd.state() != 'resolved')
+                $.ajax({
+                    url: "ajax.php/help/tips/install",
+                    dataType: 'json',
+                    success: function (json_config) {
+                        dfd.resolve(json_config);
+                    }
+                });
+            return dfd;
+        }
+    })();
 
-    $('.tip').live('mouseover click', function(e) {
+    $('.tip')
+    .each(function(i, e) {
+        e.rel = 'tip-' + i;
+    })
+    .live('mouseover click', function(e) {
         e.preventDefault();
         var tip_num = this.rel;
 
         if($('.' + tip_num).length == 0) {
 
-            var elem = $(this);
-            var pos = elem.offset();
-
-            var y_pos = pos.top - 12;
-            var x_pos = pos.left + elem.width() + 20;
+            var elem = $(this),
+                pos = elem.offset(),
+                y_pos = pos.top - 12,
+                x_pos = pos.left + elem.width() + 20,
+                tip_arrow = $('<img>')
+                    .attr('src', './images/tip_arrow.png')
+                    .addClass('tip_arrow'),
+                tip_box = $('<div>')
+                    .addClass('tip_box'),
+                tip_content = $('<div>')
+                    .append('<a href="#" class="tip_close">x</a>')
+                    .addClass('tip_content'),
+                the_tip = tip_box
+                    .append(tip_arrow)
+                    .append(tip_content)
+                    .css({
+                        "top":y_pos + "px",
+                        "left":x_pos + "px"
+                    })
+                    .addClass(tip_num),
+                tip_timer = setTimeout(function() {
+                    $('.tip_box').remove();
+                    $('body').append(the_tip.hide().fadeIn());
+                }, 500);
 
-            var tip_arrow = $('<img>').attr('src', './images/tip_arrow.png').addClass('tip_arrow');
-            var tip_box = $('<div>').addClass('tip_box');
-            var tip_content = $('<div>').addClass('tip_content').load('tips.html '+elem.attr('href'), function() {
-                tip_content.prepend('<a href="#" class="tip_close">x</a>');
+            elem.live('mouseout', function() {
+                clearTimeout(tip_timer);
             });
 
-            var the_tip = tip_box.append(tip_arrow).append(tip_content);
-            the_tip.css({
-                "top":y_pos + "px",
-                "left":x_pos + "px"
-            }).addClass(tip_num);
-
-            tip_timer = setTimeout(function() {
-                $('.tip_box').remove();
-                $('body').append(the_tip.hide().fadeIn());
-            }, 500);
-
+            getHelpTips().then(function(tips) {
+                var section = tips[elem.attr('href').substr(1)];
+                if (!section) {
+                    elem.remove();
+                    clearTimeout(tip_timer);
+                    return;
+                }
+                tip_content.append(
+                    $('<b>').append(section.title))
+                    .append(section.content);
+            });
             $('.' + tip_num + ' .tip_shadow').css({
                 "height":$('.' + tip_num).height() + 5
             });
         }
-    }).live('mouseout', function() {
-        clearTimeout(tip_timer);
     });
-    $('body').delegate('.tip_close', 'click', function(e) {
+
+    $('body')
+    .delegate('.tip_close', 'click', function(e) {
         e.preventDefault();
         $(this).parent().parent().remove();
     });