Laravel, right way to import javascript into Blade Templates

104,945

Solution 1

Anything outside of your @section block will not be rendered.

You could edit your layouts/app.blade.php and add a @stack('head') where you want your styles/javascript to appear (preferably in the <head> section of your HTML).

In any blade file that @extends('layouts.app') you can then use

@push('head')
<!-- Styles -->
<link href="{{ asset('css/pizza.css') }}" rel="stylesheet">
<!-- Scripts -->
<script src="{{ asset('js/components/pizza.js')}}"></script>
@endpush

to push content into that stack.

For more information visit https://laravel.com/docs/5.6/blade#stacks

Solution 2

For custom scripts on specific page,

  • add @yield('footer-scripts') to layouts/app.blade.php

  • create a folder named 'scripts' in views folder

  • inside views/scripts folder create a file 'pizza-script.blade.php' and add the js file contents inside

    <script src="/path/to/pizza.js" />   <!-- it might not work if path isn't clear -->
    
    <script type="text/javascript">
        console.log('executing js here..')
       js file contents....
    
      #if jquery needed add it like, 
    
      $(document).ready(function(){
        ...
      }
    </script>
    
  • in your index.blade.php (or the page where you want the scripts to execute) at the end add the script after @endsection

      @section('footer-scripts')
          @include('scripts.pizza-script')
      @endsection
    

now refresh the page, you can see 'executing js here..' on the console.

Solution 3

Try to move pizza.js at the bottom of index.blade.php

    @section('extra-script')

    {{Html::script('js/components/pizza.js')}}

    @endsection

Hope it helps.

Share:
104,945
Andre
Author by

Andre

Hey there, thanks for checking by! 👋 My name is Andre and I am a full stack developer and tech enthusiast. I cannot get enough of React, JavaScript, web, voice UIs, and more! Please visit my personal website or my GitHub profile for more information about me. Or hit me up on Twitter or LinkedIn. I love to chat about tech and IT. I wish you an awesome day!

Updated on January 20, 2022

Comments

  • Andre
    Andre over 2 years

    I am using Laravel 5.6. This page did not work for me.

    pizza/index.blade.php looks like this:

    @extends('layouts.app')
    
    
    @section('content')
        <!-- Styles -->
        <link href="{{ asset('css/pizza.css') }}" rel="stylesheet">
        <!-- Scripts -->
        <script src="{{ asset('js/components/pizza.js')}}"></script>
        <div class="container">
            <div class="row justify-content-center">
                <div class="card">
                    <div class="card-header">Pizza</div>
                    <div class="card-body">
                        <form action="/pizzas" method="post">
                            @if ($errors->any())
                                <div class="alert alert-danger" role="alert">
                                    Please fix the following errors
                                </div>
                            @endif
                            @include('pizza.table')
                        </form>
                    </div>
                </div>
            </div>
        </div>
    @endsection
    

    pizza/table.blade.php:

    <div class="pizza-selection">
        <b>Thanks god its pizza day! Select your pizza of the day!</b>
        <table id="pizzas" class="md-box">
            <tr>
                ...
            </tr>
            @foreach ($pizzas as $pizza)
                ...
            @endforeach
            <tr>
                ...
                <input type="button" class="md-box btn btn-default" 
                 id="add_new_pizza" onClick="addPizza()" value="Add Pizza!">
                </td>
            </tr>
        </table>
        ...
    

    I get a reference error when I click on the "add_new_pizza" button, onClick="addPizza()", addPizza() is not defined. However, I try to import pizza.js in index.blade.php

    <script src="{{ asset('js/components/pizza.js')}}"></script>
    

    printing out asset('js/components/pizza.js') returns http://localhost:8080/js/components/pizza.js which looks right to me.

    public/js/components/pizza.js looks like follows:

    import PizzaService from '../services/PizzaService.js';
    
    async function addPizza(){
        // some functionality
    }
    

    It also worked when I had the function addPizza() inside the script at .blade.php.

    Also, find the repository on GitHub if you need any further code reviews: https://github.com/andrelandgraf/laravel-docker

    EDIT: When I copy the pizza.js inside <script><script> it works fine, but I receive a SyntaxError: import declarations may only appear at top level of a module. This SyntaxError dissapears when I import the script via src like you can see in my code examples. For me, this indicates that the script is not loaded at all.

    EDIT2 & Solution: I used @kerbholz solution. I added @stack('scripts') to the bottom of the body in app.blade.php and inside @section('content') of index.blade.php I know @push('stack') the pizza.js file.

    I am now one step further but I still receive the SyntaxError stated in EDIT. Is there a workaround for that or do I just have to remove the import of PizzaService.js and add a <scipt>-Tag for this file as well?

    EDIT3: Okay this issue is not related. It looks like ES6 modules are not yet supported by browsers.