How To: Create Your Own Cookie Popup, Without The Spatie Laravel Package Enter a brief summary for this post.

How To: Create your own Cookie Popup, without the Spatie Laravel Package

It is pretty much standard practice that every website today requires a popup or alert mechanism to notify the visitor to the use of cookies and a cookie policy. As a Laravel developer I did look at the Spatie package for this and then decided to roll my own. I didn't see the point of the large(r) overhead of this composer package ― not when the implementation is so simple.

Exactly the same reason why I don't use a third party service (unless required of course). So the following below is what I use in my own private projects and it has served me very well. I tend to comment out the option to decline cookie use and storage but the choice is there you can use the code and give your visitor the choice not for the website to use cookies.

First of all the HTML. Going by the Laravel blade norms the following will be in the main template, as you can clearly see.

<!DOCTYPE html>
<html lang="{{str_replace("_", "-", app()->getLocale())}}">
    <head>
        @yield("head")
        
        <!-- ... meta data ... -->

        @if(Session::has("__accepts__"))
            <!-- put something here -->
        @endif        
    </head><body>
        <a name="top_of_page" id="top_of_page"></a>
        
        <!-- ... html for header, body and footer ... -->

        <div id="popup" style="display:none;"></div>
        
        @if(!Session::has("__accepts__"))
        <div id="cookie-bg">
            <div class="cookie-notice container-fluid rounded">
                <div class="row">
                    <div class="col-lg-12 p-2">
                        This website uses cookies to provide you with a better user experience. By using this website, you 
                        accept our use of cookies. Our <a class="fw-bold" rel="index,follow" href="{{ route("public.privacy") }}">Privacy policy</a>.
                        
                        <a class="btn w-100 btn-primary my-2 accept" role="button" href="#">Accept and Continue</a>
                        <div class="d-flex justify-content-center">
                            <!--<a class="decline" href="">Decline</a>-->
                        </div>
                    </div>
                </div>
            </div>
        </div>
        <div id="cookie-nag" style="display:none;">
            <div class="cookie-notice container-fluid rounded border">
                <div class="row">
                    <div class="col-lg-12 p-2">
                        This website uses cookies to provide you with a better user experience.

                        <a class="btn w-100 btn-primary btn-sm my-2 accept" role="button" href="#">Accept</a>
                    </div>
                </div>
            </div>
        </div>
        @else
        <div id="cookie-bg" style="display:none;"></div>
        @endif

        @if(Session::has("__declines__"))
        <div id="cookie-nag" style="display:none;">
            <div class="cookie-notice container-fluid rounded border">
                <div class="row">
                    <div class="col-lg-12 p-2">
                        This website uses cookies to provide you with a better user experience.

                        <a class="btn w-100 btn-primary btn-sm my-2 accept" role="button" href="">Accept</a>
                    </div>
                </div>
            </div>
        </div>
        @endif
    </body>
        <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js" crossorigin="anonymous"></script>
        <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" crossorigin="anonymous"></script>
       
        <script>

            $(document).on("click", ".close-popup", function(e) 
            { 
                e.preventDefault();
                $("#popup").fadeOut("slow");
            });

            @if(Session::has("__declines__") and !Session::has("__accepts__"))
            $(document).ready(function() 
            {
                $("#cookie-nag").show();
                $(".accept").click(function(e) 
                {
                    e.preventDefault(); 
                    
                    $.ajax({
                        type: "GET"
                      , url: "{{ route("public.cookies.accept") }}"
                      , data: ""
                      , cache: false
                      , dataType: "text"
                      , beforeSend: function(rs) {}
                      , success: function(rs) 
                        {
                            window.location.reload();
                        }
                    });
                });
            });
            @endif

            @if(!Session::has("__declines__"))
            @if(!Session::has("__accepts__"))
            $(document).ready(function() 
            {
                if(!(window.location.href.indexOf("privacy") > -1)) 
                { 
                    $("#cookie-bg").fadeTo(200, 1);
                    $(".accept").click(function(e) 
                    {
                        e.preventDefault(); 
                        
                        $.ajax({
                            type: "GET"
                          , url: "{{ route("public.cookies.accept") }}"
                          , data: ""
                          , cache: false
                          , dataType: "text"
                          , beforeSend: function(rs) {}
                          , success: function(rs) 
                            {
                                window.location.reload();
                            }
                        });
                    });
                }

                $(".decline").click(function(e) 
                {
                    e.preventDefault();
                    
                    $.ajax({
                        type: "GET"
                      , url: "{{ route("public.cookies.decline") }}"
                      , data: ""
                      , cache: false
                      , dataType: "text"
                      , beforeSend: function(rs) {}
                      , success: function(rs) 
                        {
                            $("#cookie-bg").fadeOut(200);
                            $("#cookie-nag").fadeIn(200);
                        }
                    });
                });
            });
            @endif
            @endif
            
        </script>
        @yield("scripts")
</html>

What happens is this. If you leave as is then the visitor has no option but to accept the use of cookies to continue. They do have the option to read the cookie policy or privacy policy without the notice however ― as you'll see the JQuery does a check on a given url for this purpose. If you do decide to uncomment the decline option and the visitor declines the use of cookies then there's a smaller notice to the bottom left of the screen on every page.

That notice doesn't disappear until the visitor accepts the use of cookies. In the above HTML you see the part in the <HEAD /> with a check on Laravel's SESSION. When a visitor accepts the policy a session variable is set (__accepts__) and you can use this to allow for numerous things such as advertisement, banners and so on. If a visitor declines the use of cookies then you can use the __declines__ session variable instead to determine your course of action.

That's all there is to it really. You will of course need to create the routes and a controller and put the following two class methods in the controller, seen below.

public function acceptsCookies()
    {   
        session()->put('__accepts__', time());
        session()->save();
    }

    public function declinesCookies()
    {
        session()->put('__declines__', time());
        session()->save();
    }
	div#cookie-nag > div.cookie-notice 
	{
  		width: 256px;
  		height: auto !important;
  		background-color: #fff;
  		position: fixed;
  		bottom: 2em;
  		left: 2em;
  		z-index: 999999;

  		font-size: 80%;
	}

	div#cookie-bg > div.cookie-notice 
	{
  		width: 50%;
  		height: auto !important;
  		background-color: #fff;
  		position: fixed;
  		top: 50%;
  		left: 50%;
  		transform: translateX(-50%) translateY(-50%);
	}

	div#cookie-bg 
	{
  		position: fixed;
  		top: 0;
  		left: 0;
  		z-index: 999;
  		height: 100%;
  		width: 100%;
  		background: rgba(0, 0, 0, 0.8);
  		display: none;
	}

div#popup 
	{
  		position: fixed;
  		top: 0;
  		left: 0;
  		z-index: 9999999;
  		height: 100%;
  		width: 100%;
  		background: rgba(0, 0, 0, 0.8);
  		display: none;
	}

	div#popup > div
	{
  		width: 50%;
  		height: auto !important;
  		background-color: #fff;
  		position: fixed;
  		top: 50%;
  		left: 50%;
  		transform: translateX(-50%) translate(-50%);
	}

I use Bootstrap and there is a little CSS for the notice but as you can see this is a clean and bloat free solution and why I prefer not to use the Spatie package. This will suffice for most websites. The vast majority of people don't actually care about cookie policy options, they'll either accept or decline (in most cases given the choice they decline) or simply leave and go elsewhere. Enjoy.