Laravel Cookie Consent With Bootstrap and Axios

Web CookiesLaravel cookie consent by the developers at Spatie in Belgium is an awesome and easy to use cookie consent package for Laravel. It has a lot of translations that are provided by the community. The package places a banner at the footer of your website or application and asks the visitor for consent so you can place cookies.

The default styling uses TailwindCSS, so if you already use that you almost don’t need to do anything but maybe change the appearance a bit to match the styling of your website. I use Bootstrap 5 for all my websites so I needed to update the dialog to implement Bootstrap components. If you also use Bootstrap, follow along to make a couple of changes to make this package compatible with Bootstrap and also implement Axios to set the Cookie.

Laravel Cookie Consent

By default this package uses document.write to set the cookie, and in most browsers now cookies are only valid for 7 days when using this method. That’s why you can use Axios to set the cookie.

Bootstrap 5 implementation

Install the package

Installing the Laravel Cookie Consent package is really easy and straightforward:

  • Install the package with Composer
composer require spatie/laravel-cookie-consent
  • Publish the config file
php artisan vendor:publish --provider="Spatie\CookieConsent\CookieConsentServiceProvider" --tag="cookie-consent-config"
  • Publish the dialog contents
php artisan vendor:publish --provider="Spatie\CookieConsent\CookieConsentServiceProvider" --tag="cookie-consent-views"
  • Optionally, you can also publish the language files if you want to customise that:
php artisan vendor:publish --provider="Spatie\CookieConsent\CookieConsentServiceProvider" --tag="cookie-consent-translations"

I’d recommend to read the whole installation guide, there might be some useful information that’s good to know before implementing this on your website.

Bootstrap 5 cookie dialog

While this package is really easy to implement, it only provides TailwindCSS styling. So if you are using Bootstrap 5 like me, you need to make a couple of changes:

  • Open up the file that you have just published:
/resources/views/vendor/cookie-consent/dialogContents
  • Update the file to something like this:
<div class="cookie-consent fixed-bottom rounded-top rounded-0 shadow-lg alert bg-dark text-center mb-0" role="alert">

    <h4 class="alert-heading text-white"><i class="fas fa-fw fa-cookie-bite me-2"></i>Cookies</h4>

    <!-- Cookie Message -->

    <p class="text-white">

        {{ __('cookie-consent::texts.message') }}

    </p>

    <!-- Btn: Accept Cookies -->

    <a class="cookie-consent-agree btn btn-success col-12 col-md-auto mx-auto text-white text-decoration-none mb-3" title="{{ __('cookie-consent::texts.agree') }}">

        <i class="fas fa-fw fa-check-circle me-2"></i><strong>{{ __('cookie-consent::texts.agree') }}</strong>

    </a>

</div>

Off course every website and implementation is different so maybe you need to make small adjustments to match your website implementation. For example, if you want to use different colours change the bg-dark property to something you want. I also used FontAwesome to add a couple if nice icons. Optionally you can also add a button that links to your Cookie Policy.

  • Update the z-index for the cookie banner by adding this to your CSS:
.cookie-consent {

  z-index: 999;

}

As mentioned before, you may need to make adjustments to match your website implementation.

  • Add the Cookie dialog in your blade template:
//in your blade template
@include('cookie-consent::index')

Now you have implemented the Laravel Cookie Consent package with Bootstrap!

Using Axios JavaScript library to set cookies

By default, this package uses document.write to set the cookie in the browser. Because of new tracking prevention methods that browsers have introduced, this is not the best method for placing cookies. For example, by using document.write, cookies placed in the Safari browser are only valid for 7 days!

That’s because of the Intelligent Tracking Prevention that’s been added to Safari over the last couple of years. To workaround this, use Axios to send a POST request to a controller that sets the cookie. This way you can set cookies with an expiration date for example 5 years in the future. If you use document.write, users of your website need to give consent every 7 days, and that’s not very user friendly!

Install Axios

  • Install Axios with NPM or the method of your choice. The method below is for Laravel Mix:
npm install axios
  • Implement the Axios library in your javascript assets:
window.axios = require("axios");

window.axios.defaults.headers.common['X-Requested-Width'] = 'XMLHttpRequest';
  • Generate new assets
npm run dev

Make changes to Cookie Consent javascript

Now you need to make some changes to the javascript that comes with this package. Instead of using document.write, we are going to use Axios to send a POST request to a controller that sets the cookie.

  • Open the file
/resources/views/vendor/cookie-consent/index.blade.php
  • Update the contents of this function to something like the following
window.laravelCookieConsent = (function () {

            function consentWithCookies() {

                hideCookieDialog();

                window.axios.post('{{ route('cookie-consent') }}').catch(error => {

                    console.error(error);

                });

            }

            function hideCookieDialog() {

                const dialogs = document.getElementsByClassName('cookie-consent');

                for (let i = 0; i < dialogs.length; ++i) {

                    dialogs[i].style.display = 'none';

                }

            }

            function cookieExists(name) {

                return (document.cookie.split('; ').indexOf(name + '=' + 1) !== -1);

            }

            if (cookieExists('{{ $cookieConsentConfig['cookie_name'] }}')) {

                hideCookieDialog();

            }

            const buttons = document.getElementsByClassName('cookie-consent-agree');

            for (let i = 0; i < buttons.length; ++i) {

                buttons[i].addEventListener('click', consentWithCookies);

            }

            return {

                consentWithCookies: consentWithCookies,

                hideCookieDialog: hideCookieDialog

            };

        })();
  • Make the new CookieConsent controller with:
php artisan make:controller CookieConsentController
  • Add the following to this controller, this sets the cookie with a name as configured in the config
     /**

     * User has accepted to place cookies, set the consent cookie to remove cookie notice banner.

     *

     * @return \Illuminate\Http\JsonResponse

     */

    public function consent()

    {

        return response()

            ->json(['cookie_consent' => true])

            ->cookie(config('cookie-consent.cookie_name'), 1, 2628000);

    }
  • Add the route
// Cookie Consent

Route::post('/cookie-consent', [CookieConsentController::class, 'consent'])->name('cookie-consent');

Test the changes

If everything went well, you can now see an Ajax POST request if you accept cookies in the dialog to your controller that sets the cookie. Now you have set a cookie with a duration of 5 years instead of 7 days in most browsers, so your users are not bothered with the same question every 7 days!