I am making a site with a lots of JS, and I am wondering where I should put the JS code. Optimally I would like to keep the JS with each module and not the theme layer. Some content could be exposed as blocks etc.

But I am having some issues with the cache. In my example I need to add JS & CSS to the node edit form. I have used hook_block_view, but it is cached. So if there is an error in the node edit form, the drupal_add_js & drupal_add_css functions are not called. The same seems to be true for hook_node_prepare.

Where would you input the JS & CSS layer? and are there hooks that get's called even if there is an error in the node edit form?

  • If you wish to add JS and CSS to the node edit page in particular (or any form in general), the best and the right place to do so is the hook_form_alter() and the property you should be using is #after_build. This comment on DO tells you exactly what to do - drupal.org/node/1253520#comment-4881588 Hope this helps :-) Commented Feb 13, 2012 at 5:29
  • Thanks, just what I needed. Got a nice form now, much better than the default he he. Any opinions about the architecture of such a site?
    – Jens
    Commented Feb 13, 2012 at 6:41
  • Glad it worked. When it is so you should you should mark the answer as 'answer accepted' so the question does not appear in the list of unanswered questions and the person helping you out gets "karma". I see that you are new here. I am too, but I have more active accounts on other StackOverflow services, and I love this place. Commented Feb 13, 2012 at 8:19
  • And oh.. just knowing that you need JS CSS on a form and trying to comment on the architecture of the site would be no less than a crime :-p Commented Feb 13, 2012 at 8:21
  • Sure, answered now.
    – Jens
    Commented Feb 17, 2012 at 7:06

2 Answers 2


You should use the #attached property to ensure that JS/CSS always gets loaded properly together with another render element. It can also be used to set more values at the same time, as the example code on drupal_process_attached() shows. (That example code is for a generic render array, but it can be used also for a form array.)

$form['#attached'] = array(
  'js' => array(
    drupal_get_path('module', 'taxonomy') . '/taxonomy.js',
  'css' => array(
    drupal_get_path('module', 'taxonomy') . '/taxonomy.css',

It also works for JavaScript files hosted somewhere else.

$form['#attached']['js'] = array(
  'http://code.jquery.com/jquery-1.4.2.min.js' => array(
    'type' => 'external',

As side note, it also works for HTTP headers.

$form['#attached']['drupal_add_http_header'] = array(
    'application/rss+xml; charset=utf-8',

I feel that these answers and comments desperately needed example code, particularly those of @AyeshK and @Letharion.

The following example obviously adds CSS, but it would be nearly identical for adding JavaScript.

Using @Sumeet's answer, but using the #attached property instead of calling drupal_add_css(), the code is the following.

 * Implements hook_form_FORM_ID_alter().
function MY_MODULE_form_MY_FORM_ID_alter(&$form, &$form_state, $form_id) {
  $form['#after_build'][] = 'MY_MODULE_some_function_name_after_build';

function MY_MODULE_some_function_name_after_build($form, &$form_state) {
  $style_path = drupal_get_path('module','MY_MODULE') . '/css/my_css.css';
  // drupal_add_css('file', $style_path);
  $form['#attached']['css'][] = $style_path;
  return $form;

Finally, the deprecation of drupal_add_css() is described in the drupal_add_css(), drupal_add_js() and drupal_add_library() removed in favor of #attached change record.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.