8.5.x theme.api.php hook_js_alter(&$javascript, \Drupal\Core\Asset\AttachedAssetsInterface $assets)
8.0.x theme.api.php hook_js_alter(&$javascript, \Drupal\Core\Asset\AttachedAssetsInterface $assets)
8.1.x theme.api.php hook_js_alter(&$javascript, \Drupal\Core\Asset\AttachedAssetsInterface $assets)
8.2.x theme.api.php hook_js_alter(&$javascript, \Drupal\Core\Asset\AttachedAssetsInterface $assets)
8.3.x theme.api.php hook_js_alter(&$javascript, \Drupal\Core\Asset\AttachedAssetsInterface $assets)
8.4.x theme.api.php hook_js_alter(&$javascript, \Drupal\Core\Asset\AttachedAssetsInterface $assets)
8.6.x theme.api.php hook_js_alter(&$javascript, \Drupal\Core\Asset\AttachedAssetsInterface $assets)
7.x system.api.php hook_js_alter(&$javascript)

Perform necessary alterations to the JavaScript before it is presented on the page.


$javascript: An array of all JavaScript being presented on the page.

See also




Related topics

2 functions implement hook_js_alter()

Note: this list is generated by pattern matching, so it may include some functions that are not actually implementations of this hook.

locale_js_alter in modules/locale/locale.module
Implements hook_js_alter().
simpletest_js_alter in modules/simpletest/simpletest.module
Implements hook_js_alter().
1 invocation of hook_js_alter()
drupal_get_js in includes/common.inc
Returns a themed presentation of all JavaScript code for the current page.


modules/system/system.api.php, line 746
Hooks provided by Drupal core and the System module.


function hook_js_alter(&$javascript) {

  // Swap out jQuery to use an updated version of the library.
  $javascript['misc/jquery.js']['data'] = drupal_get_path('module', 'jquery_update') . '/jquery.js';


ReeceMarsland’s picture

When following the example above my logs were filling with drupal_get_js out of scope errors. Following the commit here on adaptive theme helped me fix.



$file = drupal_get_path('theme', 'pp') . '/js/autocomplete.js';
$javascript['misc/autocomplete.js'] = drupal_js_defaults($file);

$file = drupal_get_path('theme', 'pp') . '/js/autocomplete.js';
$javascript['misc/autocomplete.js']['data'] =$file;

ac.swdev’s picture

This works for me:

function my_module_js_alter(&$javascript) {
    global $base_url;
    $jQuery_version = '1.7.2';
    //$jQuery_local = $base_url.'/'.drupal_get_path('module', 'my_module').'/jquery-1.7.2.min.js';
    $jQuery_local = $base_url.'/'.drupal_get_path('module', 'my_module').'/jquery-1.7.2.min.js?v='.$jQuery_version;
    $jQuery_cdn = 'http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js';

    $javascript['misc/jquery.js']['data']    = $jQuery_cdn;
    $javascript['misc/jquery.js']['version'] = $jQuery_version;

    $group  = $javascript['misc/jquery.js']['group']  = JS_LIBRARY;
    $weight = $javascript['misc/jquery.js']['weight'] = -20; 
    drupal_add_js('window.jQuery || document.write(\'<script type="text/javascript" src="'.$jQuery_local.'"><\/script>\')',
        array('type'=>'inline', 'scope'=>'header', 'group'=>$group, 'every_page'=>TRUE, 'weight'=>$weight));
lgrtm’s picture

Thk for posting. I saw very examples and not work but your code yes !!!
See you

manuelgc’s picture

Thanks... I test method 3 from http://drupal.org/node/1058168 but not works.. al least for me.

meenugupta’s picture


I am using below function. But it's not taking preprocess function whether true or false, 1 or 0, Please suggest how to set it.
$javascript['modules/field/modules/text/text.js']['preprocess '] = FALSE;
Getting below error:
Notice: Undefined index: preprocess in drupal_get_js() (line 4351 of C:\xamp\xampplite\htdocs\drupal\includes\common.inc).

Code is

function drupalmodule_js_alter(&$javascript) {
$javascript['modules/field/modules/text/text.js']['type'] = 'file';
$javascript['modules/field/modules/text/text.js']['scope'] = 'header';
$javascript['modules/field/modules/text/text.js']['every_page'] = TRUE;
$javascript['modules/field/modules/text/text.js']['weight'] = -20;
$javascript['modules/field/modules/text/text.js']['group'] = 0;
$javascript['modules/field/modules/text/text.js']['preprocess '] = FALSE;
$javascript['modules/field/modules/text/text.js']['defer'] = '';
$javascript['modules/field/modules/text/text.js']['cache'] = '';
$javascript['modules/field/modules/text/text.js']['data'] = drupal_get_path('module', 'drupalmodule') . '/drupalmodule.js';

krisis’s picture

Don't set the 'preprocess' value and set 'cache' to FALSE. Drupal does not care about preprocess if the script is not cached (i.e. aggregated in one big file).

drupal@guusvandewal.nl’s picture

This fixed the errors for me:
Download a copy of jquery.form.js at http://malsup.github.io/jquery.form.js.
Put it in your theme. Don't overwrite core and use an hook_js_alter.
Thanks all

function THEMENAME_js_alter(&$javascript) {
    $javascript['misc/jquery.form.js']['data'] = drupal_get_path('theme', 'THEMENAME') . '/js/jquery.form.js';
    $javascript['misc/jquery.form.js']['scope'] = 'header';
    $javascript['misc/jquery.form.js']['group'] = 'JS_LIBRARY';
    $javascript['misc/jquery.form.js']['weight'] = '100';
    $javascript['misc/jquery.form.js']['every_page'] = TRUE;
    $javascript['misc/jquery.form.js']['type'] = 'file';
    $javascript['misc/jquery.form.js']['preprocess'] = 'TRUE';
    $javascript['misc/jquery.form.js']['cache'] = 'TRUE';
    $javascript['misc/jquery.form.js']['defer'] = 'TRUE';
drupal@guusvandewal.nl’s picture

Ow. It fixed my ajax webform submission in IE8. I did have an error occured message

kenorb’s picture

For Drupal 6 you can use:

pachabhaiya’s picture

Inside template.php file, I made the following function:

function MYTHEME_js_alter(&$javascript) {
print "Hello World!!!";

Just for testing purpose, I tried to print a text "Hello World!!!" in the above function. It displayed the output "Hello World!!!" twice.

Why is it displaying the output twice ?

wheelercreek’s picture

I believe it's because hooks run whenever they are needed.. in this case you're altering javascripts that are loaded, so if you have 2 javascripts in your theme, it would run twice. I think you just need to wrap that print command into some logic based on which javascript you're targeting (this is how hook_form_alter works too).

Jon Nunan’s picture

Hi, this alter is called each time 'drupal_get_js' is called. Themes often call this in hook_preprocess_html, it may get called multiple times for different scopes, or you might have a child theme and a parent theme that both call the function.

er.pushpinderrana’s picture

We can easily unset unused js using this hook function. It would prevent to load unused js on page that will reduce extra overhead on page. We can write this function anywhere either in custom module or template.php inside your theme.

Say I need to unset test.js then I would write code in following way:

function general_js_alter(&$javascript) {
   $test_js_path = path_to_theme() . '/js/test.js';
ibedoya’s picture

Can we use this to set variables to Drupal.settings?

For example:

function mymodule_js_alter() {
  global $user;

  drupal_add_js(array('mymodule' => array('time' => time())), 'setting');
  drupal_add_js(array('mymodule' => array('user' => $user->uid)), 'setting');

It's correct?

mathieso’s picture

Not sure, but that might create an infinite loop. drupal_add_js invokes mymodule_js_alter which calls drupal_add_js which ...

You could set a static variable and a test for it, so that your drupal_add_js statements are only run once. Or (better?) don't call drupal_add_js in mymodule_js_alter. Instead, look at the array parameter passed into module_js_alter, and add to that.

mathieso’s picture

This seems to work:

 * Implements hook_js_alter().
function cybercourse_base_js_alter(&$javascript) {
  //Make sure that JS error handling code is included.
  global $base_url;
  $path = drupal_get_path('module', 'cybercourse_base') 
        . '/js/cybercourse_base_error_handling.js';
  $javascript[$path] = array(
    'data' => $base_url. '/' . $path,
    'scope' => 'header',
    'group' => 'JS_LIBRARY',
    'every_page' => TRUE,
    'type' => 'file',
    'cache' => TRUE,
    'weight' => 0,
    'preprocess' => 1,
    'defer' => 0,
leolando.tan’s picture

Just got into this function too to alter "misc/autocomplete.js" and the issue causing the "Notice: Undefined index: scope in drupal_get_js() (line 4309 of C:\xampp\htdocs\[DRUPAL_DIR]\includes\common.inc)." error is that there are times when the hook is called but "misc/autocomplete.js" is not yet in the array w/c just adds

[misc/autocomplete.js] => Array(
  [data] => [your_custom_js],

to the array but the scope, type, and other attributes are not there. So we first need to check if the array key exists like so:

if (isset($javascript['misc/autocomplete.js'])) {
  $file = drupal_get_path('module', 'mymodule') . '/autocomplete.js';
  $javascript['misc/autocomplete.js']['data'] = $file;

That solves it. :)

bpunzalan’s picture

I use hook_js_alter for replacing my jquery.

function hook_js_alter(&$javascript) {
  // Swap out jQuery to use an updated version of the library.
  $javascript ['misc/jquery.js']['data'] = drupal_get_path('theme', 'themename') . '/js/jquery.js';

I dont know if it changes but whenever i check the version of my jquery using jQuery.fn.jquery, it returns 1.10 which is the jquery version of jquery_update. I need 1.11 for my one page theme template. I think it does not work for me.

jasom’s picture

My scenario:

I have edited friendly_register.js file belonging to the Friendly register module in order to make a better CSS sprint (less http requests == site loads faster). I did it using hook_js_alter in my custom module called "Customer". I placed an updated version of JS file right into the Customer's folder.

 * Path to friendly_register.js override. I have added 
 * into default /js/friendly_register.js in order to make better css sprint.
function  customer_js_alter(&$javascript) {
  $javascript[drupal_get_path('module', 'friendly_register') . '/js/friendly_register.js']['data'] = drupal_get_path('module', 'customer') . '/friendly_register.js';

You can find more details here.