diff --git a/include/ajax.config.php b/include/ajax.config.php
index 82d92f1ca333408a2eff3bc67c84f12d78807d39..e0df37d9787a07c46c0e67a25dadd6e5655f18a2 100644
--- a/include/ajax.config.php
+++ b/include/ajax.config.php
@@ -20,7 +20,7 @@ class ConfigAjaxAPI extends AjaxController {
 
     //config info UI might need.
     function scp() {
-        global $cfg;
+        global $cfg, $thisstaff;
 
         $config=array(
               'lock_time'       => ($cfg->getLockTime()*3600),
@@ -28,6 +28,7 @@ class ConfigAjaxAPI extends AjaxController {
               'html_thread'     => (bool) $cfg->isHtmlThreadEnabled(),
               'date_format'     => ($cfg->getDateFormat()),
               'allow_attachments' => (bool) $cfg->allowAttachments(),
+              'lang'            => $thisstaff->getLanguage(),
         );
         return $this->json_encode($config);
     }
@@ -41,6 +42,7 @@ class ConfigAjaxAPI extends AjaxController {
             'max_file_size'   => (int) $cfg->getMaxFileSize(),
             'max_file_uploads'=> (int) $cfg->getClientMaxFileUploads(),
             'html_thread'     => (bool) $cfg->isHtmlThreadEnabled(),
+            'lang'            => $cfg->getSystemLanguage(),
         );
 
         $config = $this->json_encode($config);
diff --git a/include/ajax.i18n.php b/include/ajax.i18n.php
new file mode 100644
index 0000000000000000000000000000000000000000..95fbc5dbc6379afb869c76e0a561213a00069d1a
--- /dev/null
+++ b/include/ajax.i18n.php
@@ -0,0 +1,38 @@
+<?php
+/*********************************************************************
+    ajax.i18n.php
+
+    Callbacks to get internaltionalized pieces for osticket
+
+    Peter Rotich <peter@osticket.com>
+    Jared Hancock <jared@osticket.com>
+    Copyright (c)  2006-2014 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('!');
+
+class i18nAjaxAPI extends AjaxController {
+    function getLanguageFile($lang, $key) {
+        global $cfg;
+
+        $i18n = new Internationalization($lang);
+        switch ($key) {
+        case 'redactor':
+            $data = $i18n->getTemplate('redactor.js')->getRawData();
+            header('Content-Type: text/javascript; charset=UTF-8');
+            break;
+        default:
+            Http::response(404, 'No such i18n data');
+        }
+
+        Http::cacheable(md5($data), $cfg->lastModified());
+        echo $data;
+    }
+}
+?>
diff --git a/include/class.i18n.php b/include/class.i18n.php
index 35f68f337e038c17745267f14bc69fd565563120..51cedf9a8eb3d4a9c198cf68ef474c2783ad056f 100644
--- a/include/class.i18n.php
+++ b/include/class.i18n.php
@@ -358,6 +358,14 @@ class DataTemplate {
         return $this->data;
     }
 
+    function getRawData() {
+        if (!isset($this->data) && $this->filepath)
+            return file_get_contents($this->filepath);
+            // TODO: If there was a parsing error, attempt to try the next
+            //       language in the list of requested languages
+        return false;
+    }
+
     function getLang() {
         return $this->lang;
     }
diff --git a/include/staff/footer.inc.php b/include/staff/footer.inc.php
index 32595b3c828b308492962fca4f47218095a09d1e..90e79a29eab673c1476a50a1c5c7ce9c3e47974d 100644
--- a/include/staff/footer.inc.php
+++ b/include/staff/footer.inc.php
@@ -32,6 +32,11 @@ if ($.support.pjax) {
   })
 }
 </script>
+<?php
+if ($thisstaff && $thisstaff->getLanguage() != 'en_US') { ?>
+    <script type="text/javascript" src="ajax.php/i18n/<?php
+        echo $thisstaff->getLanguage(); ?>/redactor"></script>
+<?php } ?>
 </body>
 </html>
 <?php } # endif X_PJAX ?>
diff --git a/js/redactor-osticket.js b/js/redactor-osticket.js
index e96d92a073da888b2482a54158a7ee75a1ecd87e..6df5edbe6eb2a64caa8110a71695933110b67c9e 100644
--- a/js/redactor-osticket.js
+++ b/js/redactor-osticket.js
@@ -258,7 +258,11 @@ $(function() {
             options['plugins'].push('draft');
             options.draftDelete = el.hasClass('draft-delete');
         }
-        el.redactor(options);
+        getConfig().then(function(c) {
+            if (c.lang && c.lang.toLowerCase() != 'en_us')
+                options['lang'] = c.lang.toLowerCase();
+            el.redactor(options);
+        });
     },
     findRichtextBoxes = function() {
         $('.richtext').each(function(i,el) {
diff --git a/scp/ajax.php b/scp/ajax.php
index a192cce8cf92da76bf185a441840093133d03099..cc99353e9b7513d3aec6c7a26632744aed578988 100644
--- a/scp/ajax.php
+++ b/scp/ajax.php
@@ -162,6 +162,9 @@ $dispatcher = patterns('',
     url('^/help/', patterns('ajax.tips.php:HelpTipAjaxAPI',
         url_get('^tips/(?P<namespace>[\w_.]+)$', 'getTipsJson'),
         url_get('^(?P<lang>[\w_]+)?/tips/(?P<namespace>[\w_.]+)$', 'getTipsJsonForLang')
+    )),
+    url('^/i18n/(?P<lang>[\w_]+)/', patterns('ajax.i18n.php:i18nAjaxAPI',
+        url_get('(?P<tag>\w+)$', 'getLanguageFile')
     ))
 );
 
diff --git a/setup/cli/modules/i18n.php b/setup/cli/modules/i18n.php
index c3c77668ec7e3956a175cfab424cbb0097fe434d..044e07e3380d16cef8320fd41d82548f17ed4e66 100644
--- a/setup/cli/modules/i18n.php
+++ b/setup/cli/modules/i18n.php
@@ -125,8 +125,19 @@ class i18n_Compiler extends Module {
         }
 
         // TODO: Add i18n extras (like fonts)
+        // Redactor language pack
+        list($code, $js) = $this->_http_get(
+            'http://imperavi.com/webdownload/redactor/lang/?lang='
+            .strtolower($lang));
+        if ($code == 200)
+            $phar->addFromString('redactor.js', $js);
+        else
+            $this->stderr->write("Unable to fetch Redactor language file\n");
 
         // TODO: Sign files
+
+        // Use a very small stub
+        $phar->setStub('<?php __HALT_COMPILER();');
     }
 
     function __read_next_string($tokens) {