diff --git a/.gitignore b/.gitignore
index 84d48d86e28c87459c1983a44d436fb11249ce53..49ccedc55315e49cfd7be93ceb0cf3244ad97255 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,6 +2,7 @@
 _gh_pages
 _site
 .ruby-version
+docs/_data/configBridge.json
 
 # Numerous always-ignore extensions
 *.diff
diff --git a/Gruntfile.js b/Gruntfile.js
index cbf01ac1ff47f03b8fff5b3edfe48888b467fd86..eba9a55b79b2049b4ece5cf2d23e2f460d622609 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -27,6 +27,13 @@ module.exports = function (grunt) {
   };
   var generateRawFiles = require('./grunt/bs-raw-files-generator.js');
   var generateCommonJSModule = require('./grunt/bs-commonjs-generator.js');
+  var configBridge = grunt.file.readJSON('./grunt/configBridge.json', { encoding: 'utf8' });
+
+  Object.keys(configBridge.paths).forEach(function (key) {
+    configBridge.paths[key].forEach(function (val, i, arr) {
+      arr[i] = path.join('./docs/assets', val);
+    });
+  });
 
   // Project configuration.
   grunt.initConfig({
@@ -38,21 +45,8 @@ module.exports = function (grunt) {
             ' * Copyright 2011-<%= grunt.template.today("yyyy") %> <%= pkg.author %>\n' +
             ' * Licensed under <%= pkg.license.type %> (<%= pkg.license.url %>)\n' +
             ' */\n',
-    // NOTE: This jqueryCheck/jqueryVersionCheck code is duplicated in customizer.js;
-    //       if making changes here, be sure to update the other copy too.
-    jqueryCheck: [
-      'if (typeof jQuery === \'undefined\') {',
-      '  throw new Error(\'Bootstrap\\\'s JavaScript requires jQuery\')',
-      '}\n'
-    ].join('\n'),
-    jqueryVersionCheck: [
-      '+function ($) {',
-      '  var version = $.fn.jquery.split(\' \')[0].split(\'.\')',
-      '  if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1)) {',
-      '    throw new Error(\'Bootstrap\\\'s JavaScript requires jQuery version 1.9.1 or higher\')',
-      '  }',
-      '}(jQuery);\n\n'
-    ].join('\n'),
+    jqueryCheck: configBridge.config.jqueryCheck.join('\n'),
+    jqueryVersionCheck: configBridge.config.jqueryVersionCheck.join('\n'),
 
     // Task configuration.
     clean: {
@@ -138,25 +132,11 @@ module.exports = function (grunt) {
         dest: 'dist/js/<%= pkg.name %>.min.js'
       },
       customize: {
-        // NOTE: This src list is duplicated in footer.html; if making changes here, be sure to update the other copy too.
-        src: [
-          'docs/assets/js/vendor/less.min.js',
-          'docs/assets/js/vendor/jszip.min.js',
-          'docs/assets/js/vendor/uglify.min.js',
-          'docs/assets/js/vendor/Blob.js',
-          'docs/assets/js/vendor/FileSaver.js',
-          'docs/assets/js/raw-files.min.js',
-          'docs/assets/js/src/customizer.js'
-        ],
+        src: configBridge.paths.customizerJs,
         dest: 'docs/assets/js/customize.min.js'
       },
       docsJs: {
-        // NOTE: This src list is duplicated in footer.html; if making changes here, be sure to update the other copy too.
-        src: [
-          'docs/assets/js/vendor/holder.js',
-          'docs/assets/js/vendor/ZeroClipboard.min.js',
-          'docs/assets/js/src/application.js'
-        ],
+        src: configBridge.paths.docsJs,
         dest: 'docs/assets/js/docs.min.js'
       }
     },
@@ -195,16 +175,7 @@ module.exports = function (grunt) {
 
     autoprefixer: {
       options: {
-        browsers: [
-          'Android 2.3',
-          'Android >= 4',
-          'Chrome >= 20',
-          'Firefox >= 24', // Firefox 24 is the latest ESR
-          'Explorer >= 8',
-          'iOS >= 6',
-          'Opera >= 12',
-          'Safari >= 6'
-        ]
+        browsers: configBridge.config.autoprefixerBrowsers
       },
       core: {
         options: {
@@ -312,6 +283,10 @@ module.exports = function (grunt) {
       docs: {
         src: 'dist/*/*',
         dest: 'docs/'
+      },
+      configBridge: {
+        src: 'grunt/configBridge.json',
+        dest: 'docs/_data/configBridge.json'
       }
     },
 
@@ -482,7 +457,7 @@ module.exports = function (grunt) {
   grunt.registerTask('lint-docs-css', ['csslint:docs', 'csslint:examples']);
   grunt.registerTask('docs-js', ['uglify:docsJs', 'uglify:customize']);
   grunt.registerTask('lint-docs-js', ['jshint:assets', 'jscs:assets']);
-  grunt.registerTask('docs', ['docs-css', 'lint-docs-css', 'docs-js', 'lint-docs-js', 'clean:docs', 'copy:docs', 'build-customizer']);
+  grunt.registerTask('docs', ['docs-css', 'lint-docs-css', 'docs-js', 'lint-docs-js', 'clean:docs', 'copy:docs', 'copy:configBridge', 'build-customizer']);
 
   // Task for updating the cached npm packages used by the Travis build (which are controlled by test-infra/npm-shrinkwrap.json).
   // This task should be run and the updated file should be committed whenever Bootstrap's dependencies change.
diff --git a/docs/_includes/footer.html b/docs/_includes/footer.html
index c44cabec8667da32a5df47455ba326e65740ccf0..24dfd26a5126c58f2b5e3626a6b50a48e4213152 100644
--- a/docs/_includes/footer.html
+++ b/docs/_includes/footer.html
@@ -43,25 +43,19 @@
 {% if site.github %}
   <script src="../assets/js/docs.min.js"></script>
 {% else %}
-  <script src="../assets/js/vendor/holder.js"></script>
-  <script src="../assets/js/vendor/ZeroClipboard.min.js"></script>
-  <script src="../assets/js/src/application.js"></script>
+  {% for file in site.data.configBridge.paths.docsJs %}
+  <script src="{{ file }}"></script>
+  {% endfor %}
 {% endif %}
 
 {% if page.slug == "customize" %}
+  <script>var __configBridge = {{ site.data.configBridge.config | jsonify }}</script>
   {% if site.github %}
     <script src="../assets/js/customize.min.js"></script>
   {% else %}
-    {% comment %}
-      This list is repeated in our Gruntfile—update both when making changes.
-    {% endcomment %}
-    <script src="../assets/js/vendor/less.min.js"></script>
-    <script src="../assets/js/vendor/jszip.min.js"></script>
-    <script src="../assets/js/vendor/uglify.min.js"></script>
-    <script src="../assets/js/vendor/Blob.js"></script>
-    <script src="../assets/js/vendor/FileSaver.js"></script>
-    <script src="../assets/js/raw-files.min.js"></script>
-    <script src="../assets/js/src/customizer.js"></script>
+    {% for file in site.data.configBridge.paths.customizerJs %}
+    <script src="{{ file }}"></script>
+    {% endfor %}
   {% endif %}
 {% endif %}
 
diff --git a/docs/assets/js/src/customizer.js b/docs/assets/js/src/customizer.js
index 8d9f5f7e0a04c4075dedb1ba610c30069fc22bf5..b2f15dfa036ac4c98ed333d00e8e9410a5f10c2f 100644
--- a/docs/assets/js/src/customizer.js
+++ b/docs/assets/js/src/customizer.js
@@ -6,13 +6,13 @@
  * details, see http://creativecommons.org/licenses/by/3.0/.
  */
 
-/* global JSZip, less, saveAs, UglifyJS, __js, __less, __fonts */
+/* global JSZip, less, saveAs, UglifyJS, __configBridge, __js, __less, __fonts */
 
 window.onload = function () { // wait for load in a dumb way because B-0
   'use strict';
   var cw = '/*!\n' +
            ' * Bootstrap v3.3.0 (http://getbootstrap.com)\n' +
-           ' * Copyright 2011-2014 Twitter, Inc.\n' +
+           ' * Copyright 2011-' + new Date().getFullYear() + ' Twitter, Inc.\n' +
            ' * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n' +
            ' */\n\n'
 
@@ -319,19 +319,8 @@ window.onload = function () { // wait for load in a dumb way because B-0
 
   function generateJS(preamble) {
     var $checked = $('#plugin-section input:checked')
-    var jqueryCheck = [
-      'if (typeof jQuery === \'undefined\') {',
-      '  throw new Error(\'Bootstrap\\\'s JavaScript requires jQuery\')',
-      '}\n'
-    ].join('\n')
-    var jqueryVersionCheck = [
-      '+function ($) {',
-      '  var version = $.fn.jquery.split(\' \')[0].split(\'.\')',
-      '  if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1)) {',
-      '    throw new Error(\'Bootstrap\\\'s JavaScript requires jQuery version 1.9.1 or higher\')',
-      '  }',
-      '}(jQuery);\n\n'
-    ].join('\n')
+    var jqueryCheck = __configBridge.jqueryCheck.join('\n')
+    var jqueryVersionCheck = __configBridge.jqueryVersionCheck.join('\n')
 
     if (!$checked.length) return false
 
diff --git a/grunt/configBridge.json b/grunt/configBridge.json
new file mode 100644
index 0000000000000000000000000000000000000000..84ff718728fd0352c225afe4181d3e97e279ca05
--- /dev/null
+++ b/grunt/configBridge.json
@@ -0,0 +1,44 @@
+{
+  "paths": {
+    "customizerJs": [
+      "../assets/js/vendor/autoprefixer.js",
+      "../assets/js/vendor/less.min.js",
+      "../assets/js/vendor/jszip.min.js",
+      "../assets/js/vendor/uglify.min.js",
+      "../assets/js/vendor/Blob.js",
+      "../assets/js/vendor/FileSaver.js",
+      "../assets/js/raw-files.min.js",
+      "../assets/js/src/customizer.js"
+    ],
+    "docsJs": [
+      "../assets/js/vendor/holder.js",
+      "../assets/js/vendor/ZeroClipboard.min.js",
+      "../assets/js/src/application.js"
+    ]
+  },
+  "config": {
+    "autoprefixerBrowsers": [
+      "Android 2.3",
+      "Android >= 4",
+      "Chrome >= 20",
+      "Firefox >= 24",
+      "Explorer >= 8",
+      "iOS >= 6",
+      "Opera >= 12",
+      "Safari >= 6"
+    ],
+    "jqueryCheck": [
+      "if (typeof jQuery === 'undefined') {",
+      "  throw new Error('Bootstrap\\'s JavaScript requires jQuery')",
+      "}\n"
+    ],
+    "jqueryVersionCheck": [
+      "+function ($) {",
+      "  var version = $.fn.jquery.split(' ')[0].split('.')",
+      "  if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1)) {",
+      "    throw new Error('Bootstrap\\'s JavaScript requires jQuery version 1.9.1 or higher')",
+      "  }",
+      "}(jQuery);\n\n"
+    ]
+  }
+}
\ No newline at end of file