Change record status: 
Project: 
Introduced in branch: 
8.0.x
Introduced in version: 
8.0.x
Description: 

Drupal 8 now uses asset libraries for all CSS and JS. Before this change, in order to add asset libraries in a theme, the library would have to be added site-wide or a theme would need to implement a preprocess function (which requires writing PHP).

The new attach_library() Twig function makes it possible to add libraries from within a Twig template.

Example:

core/themes/bartik/bartik.libraries.yml:

messages:
  css:
    theme:
      css/components/messages.css: {}

core/themes/bartik/templates/status-messages.html.twig:

{# In a Twig template we attach the library. #}
{{ attach_library('bartik/messages') }}
Impacts: 
Themers
Updates Done (doc team, etc.)
Online documentation: 
Not done
Theming guide: 
Not done
Module developer documentation: 
Not done
Examples project: 
Not done
Coder Review: 
Not done
Coder Upgrade: 
Not done
Other: 
Other updates done

Comments

enginpost’s picture

I love this feature. I am also curious if this means that css and js gets aggregated on a page-by-page basis? Was it always that way?

rgalaxy’s picture

can we attach it into spesific block?

feilauren’s picture

rgalaxy: Do you mean one specific instance of a block? Or the type of block? I am not sure what the use case for the former would be so I would say yes - you can identify the correct template file easily by enabling theme debug mode and inspecting the code. The library can be attached to any Twig template file, blocks included.

Edit: If you want to attach a library to a Custom Block Type, you would have to do this with a preprocessor function that will then add the block type to template suggestions when you have your debugging enabled.

silentbob’s picture

I love this feature too. Is it possible to pass a variable via {{ attach_library('bartik/messages') }} to the attached javascript library?

kakar’s picture

You can add js to the library and then attach the library. {{ attach_library('bartik/myLibrary') }}

myLibrary:
  version: 1.12
  js:
    js/some.js: {}
  css:
    component:
      css/dashboard.css: {}
  dependencies:
    - core/jquery
Sumit kumar’s picture

Hi

Can we add multiple library in same twig e.g {{ attach_library('bartik/messages','bartik/messages1') }}

taoti_admin’s picture

Hey Sumit - I am sure you have figured this out by now but maybe this will help someone in the future. The way you attach multiple libraries is just by including {{ attach_library() }} multiple times. So in your example's case:

{{ attach_library('bartik/messages') }}
{{ attach_library('bartik/messages1') }}
jjmackow’s picture

any way of getting a nonce element (Content Security Policy 3) added into the <script> and <style> tags as they are being parsed into the page?
a 'nonce' is a base64encoded string that is generated and put into the header of the page's CSP. It is intended to be random ONCE , so page caching cannot be used in order to adhere to the policy standards. It's added to the

and tags within a page as an element like , corresponding to the same page header's Content Security Policy section under script-src
Content Security Policy
 script-src 'nonce-randomNonceString' 'strict-dynamic' https: http:; object-src 'none'

cheers,

kev

apotek’s picture

All the code samples on this page assume the library is defined in a theme. I set up a module with a library, and tried to include it and it doesn't work. Is that intended not to work, or am I doing it wrong?

my_module/my_module.libraries.yml:

my_third_party_js:
  version: 1.x
  js:
    //example.com/javascript/library.min.js:
      type: external
      minified: true

And in my template file at bottom:
{{ attach_library('my_module/my_third_party_js') }}

mah ham

glennnz’s picture

@apotek, did you get this working? I can't get it to work either....

Glenn
THECA Group