How to add Custom JS / CSS to drupal site

How to add Custom JS / CSS to Drupal 7 page in theme for a better user experience

Adding JS adds dynamic presentation effects to a theme for a better user experience.

In One of the project when i had been asked to display a custom error message to the User login page, when user tried with 3 or more failed attempt. On the other hand we can handle the error using form_set_error or drupal_set_message. What if we want to include that error message to be displayed on specific position.there comes add_js into picture. I have created a hook_form_alter inside that called a custom form validation. Under that custom form validation by checking the user login count, calling an js to the user page. Sleek and simple way to do the JS

When we work with theming or module development we required to add  custom js / css to our theme or module and Adding own CSS/JS to the Drupal page is easy and multiple approach is available in drupal to do this. But the best approach to do is to get the exact requirement and understand what is best way to handle css/ js for that period of time.

Below are the list of approach

  • drupal_add_css(), drupal_add_js()
  • including in .info file
  • [‘#attached’] attribute
  • drupal_add_library()
  • hook_css_alter(&$css), hook_js_alter(&$js)
  • drupal_add_html_head()

Including as html in .tpl.php

1. drupal_add_css(), drupal_add_js()

In Drupal, drupal_add_js() & drupal_add_css() are functions to add JS/CSS to the module or theme layer. This method is used by most of the developer. Which is easy to use and can be inserted wherever you want, can be inserted online, can be added file as cache easy to find documentation. On the other hand it can be found anywhere in the codebase where it is difficult to search sometimes and you are not expecting to be there. Adding multiple file can lead to a big mess. And also require proper naming convention if you make change in js or css file. You need to add the same name to everywhere in  the code where you have used drupal_add_js() & drupal_add_css().

drupal_add_js(drupal_get_path(‘module’, ‘example’) . ‘/example.js’);

drupal_add_js('jQuery(document).ready(function () { alert("Hello!"); });', 'inline');

drupal_add_css(drupal_get_path('module', 'example') . '/example.css');

drupal_add_library('example', 'drag-and-drop');


2. including in .info file

Custom Javascript file can be added to module/theme under info file. It ‘s always a better way to let the other Developer know how many more  file you are going to attached with your module or theme. Once it is has been declared & added to module/ theme file. It automatically get added to all the page. No need to declare in any of the preprocessor. Most of the themer use this approach for theming. On the other hand unusual css /js get added to un required pages.  No control over addition of css/ js to specific page. Can not be removed or set weight in .info file.

name = My theme

description = Theme developed by me.

core = 7.x

engine = phptemplate


scripts[] = mytheme.js

3. Form API [‘#attached’] Property

On of the best way to make sure which files you are going to add. Works great with CSS, JS, library. Easy to include in any of the drupal form and we have ability to add multiple files. It can be used any kind of attached data. A keyed array of type => value pairs, where the type (most often 'css', 'js', and 'library') determines the loading technique, and the value provides the options presented to the loader function.

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

    drupal_get_path('module', 'ajax_example') . '/ajax_example.js',


4. drupal_add_library()

Adding a multiple JavaScript or CSS files at the same time.

The library defines collection of JavaScript and/or CSS files, optionally uses settings, and optionally requiring another library. For example, a library can be a jQuery plugin, a JavaScript framework, or a CSS framework. This function allows modules to load a library defined/shipped by itself or a depending module, without having to add all files of the library separately. Each library is only loaded once. It allow you to reuse styles/scripts on different pages, Path and file names are stored in one function, easy to include in multiple files. On elibrary can use other library too. On the other side a Bit more code to write. And include all the files in library.


$module: The name of the module that registered the library.
$name: The name of the library to add.
$every_page: Set to TRUE if this library is added to every page on the site. Only items with the every_page flag set to TRUE can participate in aggregation.

Return value

TRUE if the library was successfully added; FALSE if the library or one of its dependencies could not be added.

5. hook_css_alter(&$css), hook_js_alter(&$js)

hook_css_alter() is designed to act on .css file before they are being included on the page .  using this hook you can easily stop a .css file or group of files from being added to the page.

function demo_css_alter(&$css) {

  $path = drupal_get_path('module', 'node') . '/node.css';



The $path variable you see above stores the path to the node.css file found in the Node module folder and is used in the unset() function to identify which array element we want to unset.


$css: An array of all CSS items (files and inline CSS) being requested on the page.

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

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';



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

These above two hooks help you to rearrange elements by weight. we can delete files you don’t need before aggregation. Easy to replace path to a specified file. And Possible to re configure the aggregation. On the other hand Adding files here is possible but a bad choice and you end up by  messing up with files here.

6. drupal_add_html_head()

This is not the  recommended way to adding your custom css/js to the page as Using this functionality we adds output to the HEAD tag of the HTML page.This function can be called as long as the headers aren't sent. Pass no arguments (or NULL for both) to retrieve the currently stored elements. It’s is very difficult for understand where the code is included.


 * [THEME] Preprocess function for the html theme hook.


function themename_preprocess_html(&$variables) {

  $front_page = drupal_is_front_page();

  if ($front_page) {

    $variables['head_title'] = 'Jesús Heredia | Web Developer';

    // Add the description meta tag to the header

    $meta_description = array(

      '#type' => 'html_tag',

      '#tag' => 'meta',

      '#attributes' => array(

        'name' => 'description',

        'content' => "Jesús Heredia's personal website. Web Development on HTML5, CSS3, JavaScript, PHP, and Drupal.",



    drupal_add_html_head($meta_description, 'meta_description');



Syntax: drupal_add_html_head($data = NULL, $key = NULL)


$data: A renderable array. If the '#type' key is not set then 'html_tag' will be added as the default '#type'.

$key: A unique string key to allow implementations of hook_html_head_alter() to identify the element in $data. Required if $data is not NULL.

7. Including as html in .tpl.php
Yes we can add as html file in .tpl.php or printing it. Hope those methods come in handy for you. Make sure to use them in dependence of conditions you meet.

Conclusion: I personally feel to use drupal_add_library and [‘#attached’]. The form attached is really awesome and it’s very easy to understand what’s going on without scrolling through all the code.If you have any other idea just share across us over comment. want to find out more.