How do I add js and css files to frontend page loads via a plugin? I did reference this issue: Can a plugin add JS or CSS to the control panel?

but that is for Craft 2.

Reading the docs here: https://docs.craftcms.com/v3/changes-in-craft-3.html#template-tags and here https://docs.craftcms.com/v3/extend/asset-bundles.html

show that Craft 3 is much different. I've looked through several Craft 3 plugins that do load scripts and styles on the frontend but each seems to handle this in very different ways. Is there a straight-forward standard that should be used if a plugin is loaded and needs to add resources to frontend page loads?

On the Asset Bundles doc page, it seems you can link directly to the asset in the plugin init but a comment further down the page suggests that you need to load the assets into the template:

"With that in place, all that is left is to register the asset bundle wherever its JS/CSS files are needed."

or I may be understanding this incorrectly. Can I accomplish what I'm trying just by placing:

$this->sourcePath = '@ns/prefix/resources';
    $this->depends = [
        CpAsset::class,
    ];

    $this->js = [
        'custom-scripts.js',
    ];

    $this->css = [
        'custom-styles.css',
    ];

within the init function? Is this enough to get those files onto the frontend loads or do I need something else and something to tell them not to load onto backend pages?

Thank you for any help. Most of my plugin knowledge is based on reverse engineering plugins and in this area I'm still confused.

up vote 2 down vote accepted

Did you place the init function within your asset bundle class as stated in the docs?

e.g.:

<?php
namespace ns\prefix;

use craft\web\AssetBundle;
use craft\web\assets\cp\CpAsset;

class MyPluginAsset extends AssetBundle
{
    public function init()
    {
        // define the path that your publishable resources live
        $this->sourcePath = '@ns/prefix/resources';

        // define the dependencies
        $this->depends = [
            CpAsset::class,
        ];

        // define the relative path to CSS/JS files that should be registered with the page
        // when this asset bundle is registered
        $this->js = [
            'script.js',
        ];

        $this->css = [
            'styles.css',
        ];

        parent::init();
    }
}

If so, there is only one step left to register the asset in your template (e.g. yourplugin/src/templates/index.twig), you simply have to register it in your template with:

{% do view.registerAssetBundle("ns\\prefix\\FooBundle") %}

If it still does't work, you could generate a minimalistic plugin scaffolding with https://pluginfactory.io/ , its all set up for you and commented out.

Update: To register the plugins assetbundle in your frontend layout, add

<body>
  {{ beginBody() }
    .
    .
    .
    content
    .
    .
    .
    {% do view.registerAssetBundle("ns\\prefix\\FooBundle") %}
  {{ endBody() }}
</body>

to your frontend templates, e.g. in your main layout.twig at the start and the end of the body tag.

  • Thanks! I did read the docs but found it a little difficult to piece together exactly where some of this stuff went. I'll have to read more of the plugin factory comments. – Indigo Viking Dec 6 at 12:47
  • I wasn't able to get my scripts onto the page so I created a new scaffold via Plugin Factory. It worked but only loads the scripts onto the plugin's settings page in the dashboard. Is there something I need to change to get it to the frontend pages? It registers the asset bundles in templates/index.twig but most of the code references cp layouts. – Indigo Viking Dec 7 at 13:23
  • So you do want to make use of the plugins css and js assets not only in the cp but also on the regular frontend? So that your plugin modifies what you would usualy sort out with css and js linked in your frontend layout.twig? – HendrikEng Dec 7 at 19:09
  • Yes correct. The plugin doesn't need the css/js files for the backend. It needs to add the css and js files to the frontend to all pages. – Indigo Viking Dec 7 at 19:13
  • updated the answer – HendrikEng Dec 7 at 19:27

I found Yii's documentation on Assets to be helpful in understanding how to get asset dependencies. Assets https://www.yiiframework.com/doc/guide/2.0/en/structure-assets Asset Bundle Class documentation https://www.yiiframework.com/doc/api/2.0/yii-web-assetbundle

  • So from the first link, the top example, would that be what Plugin Factory generates for PluginNameAsset in the assetbundles folder? I looked through the craft3 class reference docs but mostly found craft\web\assets listed for cp side . is there a specific front end reference that Im missing? Or can I just use that first link template and reference it from my plugin main file init? Sorry Im fairly new to this, mostly just twig filters so far. – Indigo Viking Dec 7 at 21:49
  • 1
    This should be all you need {% do view.registerAssetBundle("ns\\prefix\\FooBundle") %} – bshelling Dec 7 at 21:57
  • 1
    For example if your plugin directory is structured like so: plugin-name/src/FooBundle.php – bshelling Dec 7 at 22:00
  • Thank you! I'll give that a shot! – Indigo Viking Dec 8 at 1:25
  • Still struggling to get asset bundles to frontend pages. I have the bundles setup and can get stuff go to the setting page of the plugin with a new Plugin Factory generation. Shouldn't I be able to just create a new file in the templates folder of the plugin then call Craft::$app->getView()->renderTemplate('pluginName/templateFile'); and it output the asset bundle that is registered in that file with {% do view.... - obviously doesn't work that way cause page errors with "unable to find template"... – Indigo Viking Dec 8 at 15:39

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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