<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-US">
                        <id>https://sinnbeck.dev/feed</id>
                                <link href="https://sinnbeck.dev/feed" rel="self"></link>
                                <title><![CDATA[Sinnbeck.dev]]></title>
                    
                                <subtitle>Sinnbeck.dev blog posts.</subtitle>
                                                    <updated>2022-09-13T14:00:20+00:00</updated>
                        <entry>
            <title><![CDATA[Rate limiting routes in Laravel - with tests]]></title>
            <link rel="alternate" href="https://sinnbeck.dev/posts/rate-limiting-routes-in-laravel-with-tests" />
            <id>https://sinnbeck.dev/8</id>
            <author>
                <name><![CDATA[René Sinnbeck]]></name>
                <email><![CDATA[-]]></email>

            </author>
            <summary type="html">
                <![CDATA[<h1>Rate limiting routes in Laravel - with tests</h1><p>I just had to do some work on some rate limits on a few routes in Laravel and I could not find any resources on how to set it up, and test it properly.</p>
<h2>Setting up the rate limit</h2>
<p>Add the following code inside the <code>configureRateLimiting()</code> method in <code>RouteServiceProvider.php</code></p>
<pre><code data-theme="material-theme-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">1</span><span style="color: #FFCB6B;">RateLimiter</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">for</span><span style="color: #89DDFF;">(</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">test</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">,</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">function</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">(</span><span style="color: #FFCB6B;">Request</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">request</span><span style="color: #89DDFF;">)</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">2</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">return</span><span style="color: #A6ACCD;"> </span><span style="color: #FFCB6B;">Limit</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">perMinute</span><span style="color: #89DDFF;">(</span><span style="color: #F78C6C;">10</span><span style="color: #89DDFF;">)-&gt;</span><span style="color: #82AAFF;">by</span><span style="color: #89DDFF;">($</span><span style="color: #A6ACCD;">request</span><span style="color: #89DDFF;">-&gt;</span><span style="color: #82AAFF;">ip</span><span style="color: #89DDFF;">());</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">3</span><span style="color: #89DDFF;">});</span></div></code></pre>
<p>Here we add a new rate limiter for use in routes and name it <code>test</code>.
We set it to only allow 10 requests per minute, and track it by the clients ip address.
The route can now be added to a route (or route group) as middleware.</p>
<pre><code data-theme="material-theme-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">1</span><span style="color: #FFCB6B;">Route</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">get</span><span style="color: #89DDFF;">(</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">/test</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">,</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">[</span><span style="color: #FFCB6B;">TestController</span><span style="color: #89DDFF;">::</span><span style="color: #F78C6C;">class</span><span style="color: #89DDFF;">,</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">index</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">])-&gt;</span><span style="color: #82AAFF;">middleware</span><span style="color: #89DDFF;">([</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">throttle:test</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">]);</span></div></code></pre>
<h2>Testing that its active</h2>
<p>Add a new Feature test, and add a new test</p>
<pre><code data-theme="material-theme-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">1</span><span style="color: #C792EA;">public</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">function</span><span style="color: #A6ACCD;"> </span><span style="color: #82AAFF;">test_rate_limit_is_active</span><span style="color: #89DDFF;">()</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">2</span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">3</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">$this-&gt;</span><span style="color: #82AAFF;">get</span><span style="color: #89DDFF;">(</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">/test</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">)</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">4</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">-&gt;</span><span style="color: #82AAFF;">assertOk</span><span style="color: #89DDFF;">()</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">5</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">-&gt;</span><span style="color: #82AAFF;">assertHeader</span><span style="color: #89DDFF;">(</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">X-Ratelimit-Limit</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">,</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">10</span><span style="color: #89DDFF;">)</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">6</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">-&gt;</span><span style="color: #82AAFF;">assertHeader</span><span style="color: #89DDFF;">(</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">X-Ratelimit-Remaining</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">,</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">9</span><span style="color: #89DDFF;">);</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">7</span><span style="color: #89DDFF;">}</span></div></code></pre>
<p>We first check that the response is ok, and then check if the header has the rate limiter <code>limit</code> (max attempts per minute) and the <code>remaining</code> count.</p>
<p>Next we can check if the <code>remaining</code> goes down by 1 for each request.</p>
<pre><code data-theme="material-theme-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 1</span><span style="color: #C792EA;">public</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">function</span><span style="color: #A6ACCD;"> </span><span style="color: #82AAFF;">test_rate_limit_decreases_remaining</span><span style="color: #89DDFF;">()</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 2</span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 3</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">for</span><span style="color: #89DDFF;">(</span><span style="color: #82AAFF;">range</span><span style="color: #89DDFF;">(</span><span style="color: #F78C6C;">1</span><span style="color: #89DDFF;">,</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">10</span><span style="color: #89DDFF;">)</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">as</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">i</span><span style="color: #89DDFF;">)</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 4</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">$this-&gt;</span><span style="color: #82AAFF;">get</span><span style="color: #89DDFF;">(</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">/test</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">)</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 5</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">-&gt;</span><span style="color: #82AAFF;">assertOk</span><span style="color: #89DDFF;">()</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 6</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">-&gt;</span><span style="color: #82AAFF;">assertHeader</span><span style="color: #89DDFF;">(</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">X-Ratelimit-Remaining</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">,</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">10</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">-</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">i</span><span style="color: #89DDFF;">);</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 7</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">}</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 8</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">$this-&gt;</span><span style="color: #82AAFF;">get</span><span style="color: #89DDFF;">(</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">/test</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">)</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 9</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">-&gt;</span><span style="color: #82AAFF;">assertStatus</span><span style="color: #89DDFF;">(</span><span style="color: #F78C6C;">429</span><span style="color: #89DDFF;">)</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">10</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">-&gt;</span><span style="color: #82AAFF;">assertHeader</span><span style="color: #89DDFF;">(</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">Retry-After</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">,</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">60</span><span style="color: #89DDFF;">);</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">11</span><span style="color: #89DDFF;">}</span></div></code></pre>
<p>First we make 10 requests to the page, ensuring that <code>remaining</code> is decreased properly. We then finally check that we are refused access and cannot try again for 60 seconds.</p>
<h2>Resetting attempts</h2>
<p>If for some reason the rate limiter needs to reset on a proper request (for a page that uses signed URL's for instance) this can be a bit tricky to set up.</p>
<p>First let use add the <code>signed</code> middleware to url route to secure it</p>
<pre><code data-theme="material-theme-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">1</span><span style="color: #FFCB6B;">Route</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">get</span><span style="color: #89DDFF;">(</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">/test</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">,</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">[</span><span style="color: #FFCB6B;">TestController</span><span style="color: #89DDFF;">::</span><span style="color: #F78C6C;">class</span><span style="color: #89DDFF;">,</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">index</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">])-&gt;</span><span style="color: #82AAFF;">middleware</span><span style="color: #89DDFF;">([</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">throttle:test</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">,</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">signed</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">]);</span></div></code></pre>
<p>and a test</p>
<pre><code data-theme="material-theme-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">1</span><span style="color: #C792EA;">public</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">function</span><span style="color: #A6ACCD;"> </span><span style="color: #82AAFF;">test_signed_url_blocks</span><span style="color: #89DDFF;">()</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">2</span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">3</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">$this-&gt;</span><span style="color: #82AAFF;">get</span><span style="color: #89DDFF;">(</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">/test</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">)</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">4</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">-&gt;</span><span style="color: #82AAFF;">assertForbidden</span><span style="color: #89DDFF;">()</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">5</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">-&gt;</span><span style="color: #82AAFF;">assertHeader</span><span style="color: #89DDFF;">(</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">X-Ratelimit-Remaining</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">,</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">9</span><span style="color: #89DDFF;">);</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">6</span><span style="color: #89DDFF;">}</span></div></code></pre>
<p>Now we just need to make sure that <code>remaining</code> attempts reset after actually getting to the route. Open the <code>TestController</code> and set it up like the following</p>
<pre><code data-theme="material-theme-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 1</span><span style="color: #89DDFF;">&lt;?php</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 2</span>&nbsp;</div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 3</span><span style="color: #F78C6C;">namespace</span><span style="color: #A6ACCD;"> </span><span style="color: #FFCB6B;">App</span><span style="color: #89DDFF;">\</span><span style="color: #FFCB6B;">Http</span><span style="color: #89DDFF;">\</span><span style="color: #FFCB6B;">Controllers</span><span style="color: #89DDFF;">;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 4</span>&nbsp;</div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 5</span><span style="color: #F78C6C;">use</span><span style="color: #FFCB6B;"> </span><span style="color: #A6ACCD;">Illuminate</span><span style="color: #89DDFF;">\</span><span style="color: #A6ACCD;">Http</span><span style="color: #89DDFF;">\</span><span style="color: #A6ACCD;">Request</span><span style="color: #89DDFF;">;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 6</span><span style="color: #F78C6C;">use</span><span style="color: #FFCB6B;"> </span><span style="color: #A6ACCD;">Illuminate</span><span style="color: #89DDFF;">\</span><span style="color: #A6ACCD;">Support</span><span style="color: #89DDFF;">\</span><span style="color: #A6ACCD;">Facades</span><span style="color: #89DDFF;">\</span><span style="color: #A6ACCD;">RateLimiter</span><span style="color: #89DDFF;">;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 7</span>&nbsp;</div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 8</span><span style="color: #C792EA;">class</span><span style="color: #A6ACCD;"> </span><span style="color: #FFCB6B;">TestController</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">extends</span><span style="color: #A6ACCD;"> </span><span style="color: #FFCB6B;">Controller</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 9</span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">10</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #C792EA;">public</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">function</span><span style="color: #A6ACCD;"> </span><span style="color: #82AAFF;">index</span><span style="color: #89DDFF;">(</span><span style="color: #FFCB6B;">Request</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">request</span><span style="color: #89DDFF;">)</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">11</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">12</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FFCB6B;">RateLimiter</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">clear</span><span style="color: #89DDFF;">(</span><span style="color: #82AAFF;">md5</span><span style="color: #89DDFF;">(</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">test</span><span style="color: #89DDFF;">&#39;</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">.</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">request</span><span style="color: #89DDFF;">-&gt;</span><span style="color: #82AAFF;">ip</span><span style="color: #89DDFF;">()));</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">13</span>&nbsp;</div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">14</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">return</span><span style="color: #A6ACCD;"> </span><span style="color: #82AAFF;">view</span><span style="color: #89DDFF;">(</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">test</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">);</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">15</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">}</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">16</span><span style="color: #89DDFF;">}</span></div></code></pre>
<p>Notice here the <code>RateLimiter::clear(md5('test' . $request-&gt;ip()));</code>. This is what will reset the rate limit when the request goes through. Laravel does this by concatenating the rate limiter name, with the limit key set with <code>-&gt;by()</code>. It then hash the string with md5.</p>
<pre><code data-theme="material-theme-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">1</span><span style="color: #FFCB6B;">RateLimiter</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">for</span><span style="color: #89DDFF;">(</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">test</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">,</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">function</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">(</span><span style="color: #FFCB6B;">Request</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">request</span><span style="color: #89DDFF;">)</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">2</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">return</span><span style="color: #A6ACCD;"> </span><span style="color: #FFCB6B;">Limit</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">perMinute</span><span style="color: #89DDFF;">(</span><span style="color: #F78C6C;">10</span><span style="color: #89DDFF;">)-&gt;</span><span style="color: #82AAFF;">by</span><span style="color: #89DDFF;">($</span><span style="color: #A6ACCD;">request</span><span style="color: #89DDFF;">-&gt;</span><span style="color: #82AAFF;">ip</span><span style="color: #89DDFF;">());</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">3</span><span style="color: #89DDFF;">});</span></div></code></pre>
<p>Lets test that as well</p>
<pre><code data-theme="material-theme-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 1</span><span style="color: #C792EA;">public</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">function</span><span style="color: #A6ACCD;"> </span><span style="color: #82AAFF;">test_ratelimit_resets</span><span style="color: #89DDFF;">()</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 2</span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 3</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">$this-&gt;</span><span style="color: #82AAFF;">get</span><span style="color: #89DDFF;">(</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">/test</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">)</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 4</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">-&gt;</span><span style="color: #82AAFF;">assertForbidden</span><span style="color: #89DDFF;">()</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 5</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">-&gt;</span><span style="color: #82AAFF;">assertHeader</span><span style="color: #89DDFF;">(</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">X-Ratelimit-Remaining</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">,</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">9</span><span style="color: #89DDFF;">);</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 6</span>&nbsp;</div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 7</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">$this-&gt;</span><span style="color: #82AAFF;">withoutMiddleware</span><span style="color: #89DDFF;">(\</span><span style="color: #A6ACCD;">Illuminate</span><span style="color: #89DDFF;">\</span><span style="color: #A6ACCD;">Routing</span><span style="color: #89DDFF;">\</span><span style="color: #A6ACCD;">Middleware</span><span style="color: #89DDFF;">\</span><span style="color: #FFCB6B;">ValidateSignature</span><span style="color: #89DDFF;">::</span><span style="color: #F78C6C;">class</span><span style="color: #89DDFF;">)</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 8</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">-&gt;</span><span style="color: #82AAFF;">get</span><span style="color: #89DDFF;">(</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">/test</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">)</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 9</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">-&gt;</span><span style="color: #82AAFF;">assertOk</span><span style="color: #89DDFF;">()</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">10</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">-&gt;</span><span style="color: #82AAFF;">assertHeader</span><span style="color: #89DDFF;">(</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">X-Ratelimit-Remaining</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">,</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">10</span><span style="color: #89DDFF;">);</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">11</span><span style="color: #89DDFF;">}</span></div></code></pre>
<p>First we run a forbidden request to get the rate limiter to decrease. Next we do a secondary request where we disable the signature validation, and asserts that the <code>remaining</code> is back to 10.</p>
<h2>The end</h2>
<p>Hope that was helpful to some. As you can see, rate limit in laravel is simple to interact with once you get the basics. If you find any mistakes or have ideas for improvements, please contact me on <a href="https://twitter.com/rsinnbeck">@rsinnbeck</a></p>
]]>
            </summary>
                                    <updated>2022-09-13T14:00:20+00:00</updated>
        </entry>
            <entry>
            <title><![CDATA[Getting Vite and Laravel to work with Lando]]></title>
            <link rel="alternate" href="https://sinnbeck.dev/posts/getting-vite-and-laravel-to-work-with-lando" />
            <id>https://sinnbeck.dev/7</id>
            <author>
                <name><![CDATA[René Sinnbeck]]></name>
                <email><![CDATA[-]]></email>

            </author>
            <summary type="html">
                <![CDATA[<h1>Getting Vite and Laravel to work with Lando</h1><p>I am writing the blog post as I keep getting contacted by people who want to know how how I got Vite to work with Lando. This guide will work with both running your site with http and https.</p>
<h2>Set up Lando</h2>
<p>First we add a new service to <code>.lando.yml</code> for running node</p>
<pre><code data-theme="material-theme-palenight" data-lang="yaml" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">1</span><span style="color: #F07178;">services</span><span style="color: #89DDFF;">:</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">2</span><span style="color: #A6ACCD;">  </span><span style="color: #F07178;">node</span><span style="color: #89DDFF;">:</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">3</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">type</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">node:16</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">4</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">scanner</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #FF9CAC;">false</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">5</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">ports</span><span style="color: #89DDFF;">:</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">6</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;  </span><span style="color: #89DDFF;">-</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">3009:3009</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">7</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">build</span><span style="color: #89DDFF;">:</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">8</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;  </span><span style="color: #89DDFF;">-</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">npm install</span></div></code></pre>
<p>Here we install node version 16, and open port 3009.</p>
<p>We will also add two commands for running the dev server and building assets.</p>
<pre><code data-theme="material-theme-palenight" data-lang="yaml" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">1</span><span style="color: #F07178;">tooling</span><span style="color: #89DDFF;">:</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">2</span><span style="color: #A6ACCD;">  </span><span style="color: #F07178;">dev</span><span style="color: #89DDFF;">:</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">3</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">service</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">node</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">4</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">cmd</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">npm run dev</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">5</span><span style="color: #A6ACCD;">  </span><span style="color: #F07178;">build</span><span style="color: #89DDFF;">:</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">6</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">service</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">node</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">7</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">cmd</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">npm run build</span></div></code></pre>
<p>Rebuild your site with <code>lando rebuild -y</code> and the new service is ready.</p>
<h2>Configure vite</h2>
<p>Open the <code>vite.config.js</code> file that came with Laravel and add this server config</p>
<pre><code data-theme="material-theme-palenight" data-lang="js" class='torchlight has-focus-lines' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 1</span><span style="color: #89DDFF;">import</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">{</span><span style="color: #F07178;"> </span><span style="color: #A6ACCD;">defineConfig</span><span style="color: #F07178;"> </span><span style="color: #89DDFF;">}</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">from</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">vite</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 2</span><span style="color: #89DDFF;">import</span><span style="color: #A6ACCD;"> laravel </span><span style="color: #89DDFF;">from</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">laravel-vite-plugin</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 3</span>&nbsp;</div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 4</span><span style="color: #89DDFF;">export</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">default</span><span style="color: #A6ACCD;"> </span><span style="color: #82AAFF;">defineConfig</span><span style="color: #A6ACCD;">(</span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 5</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">plugins</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> [</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 6</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #82AAFF;">laravel</span><span style="color: #A6ACCD;">(</span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 7</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">input</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> [</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">resources/css/app.css</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">,</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">resources/js/app.js</span><span style="color: #89DDFF;">&#39;</span><span style="color: #A6ACCD;">]</span><span style="color: #89DDFF;">,</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 8</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">refresh</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #FF9CAC;">true</span><span style="color: #89DDFF;">,</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 9</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">}</span><span style="color: #A6ACCD;">)</span><span style="color: #89DDFF;">,</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">10</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;]</span><span style="color: #89DDFF;">,</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">11</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">server</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">{</span><span style="color: #A6ACCD;"> </span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">12</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">https</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #FF9CAC;">false</span><span style="color: #89DDFF;">,</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">13</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">host</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #FF9CAC;">true</span><span style="color: #89DDFF;">,</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">14</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">port</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">3009</span><span style="color: #89DDFF;">,</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">15</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">hmr</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">{</span><span style="color: #F07178;">host</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">localhost</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">,</span><span style="color: #A6ACCD;"> </span><span style="color: #F07178;">protocol</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">ws</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">},</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">16</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">},</span><span style="color: #A6ACCD;"> </span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">17</span><span style="color: #89DDFF;">}</span><span style="color: #A6ACCD;">)</span><span style="color: #89DDFF;">;</span></div></code></pre>
<p>The trick is that we set the dev server to run on http + ws. Normally this wouldnt work with a https site, but as we also set the dev server to be accessed on <code>localhost</code>, the browser will allow it anyways!</p>
<h2>That's it!</h2>
<p>Start the Vite server with <code>lando dev</code> and open your site like your normally do. Hot reloading should now be working!</p>
<p>Any problems or comments, feel free to reach out to me on <a href="https://twitter.com/rsinnbeck">@rsinnbeck</a></p>
]]>
            </summary>
                                    <updated>2022-09-05T14:00:20+00:00</updated>
        </entry>
            <entry>
            <title><![CDATA[Making a complete file uploader with progressbar using Livewire and Alpinejs]]></title>
            <link rel="alternate" href="https://sinnbeck.dev/posts/making-a-complete-file-uploader-with-progressbar-using-livewire-and-alpinejs" />
            <id>https://sinnbeck.dev/6</id>
            <author>
                <name><![CDATA[René Sinnbeck]]></name>
                <email><![CDATA[-]]></email>

            </author>
            <summary type="html">
                <![CDATA[<h1>Making a complete file uploader with progressbar using Livewire and Alpinejs</h1><p>I recently had to create a file uploader that allowed the user to both click a button and select files, or simply drag files unto the page. I decided to give Livewire a shot as it seemed interesting. My first thought was to use a js package like resumeable.js or DropZone, but after reading Livewires file upload docs, I figured it might be easier to just use the built in system and extend it with some simple JavaScript.</p>
<p><img src="/gfx/livewire-file-uploader.png" alt="Preview" /></p>
<p>You can see a demo of the final code <a href="https://sinnbeck.dev/demos/livewire-file-uploader">here</a></p>
<blockquote>
<p>This guide assumes that you have already installed the latest laravel and livewire 2.x.</p>
</blockquote>
<h2>Making the upload component</h2>
<p>First lets create the livewire component. Run this in your terminal</p>
<pre><code data-theme="material-theme-palenight" data-lang="bash" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #FFCB6B;">php</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">livewire:make</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">FileUploader</span></div></code></pre>
<p>This should give you two new files. <code>/app/Http/Livewire/FileUploader.php</code> and <code>/resources/views/livewire/file-uploader.blade.php</code></p>
<h2>Designing the uploader</h2>
<p>For designing layouts I prefer to use TailwindCss, so I will use that throughout this guide. But feel free to replace it with whatever css framework (or custom css) that you like.</p>
<p>For simplicity I am making this as a full page component, but it should work inside a blade view as well. Just remember to have both livewire scripts and the alpine cdn included in the layout.</p>
<p>Add a file in <code>/resources/views/layouts/app.blade.php</code> with this content</p>
<pre><code data-theme="material-theme-palenight" data-lang="html" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">1</span><span style="color: #89DDFF;">&lt;</span><span style="color: #F07178;">head</span><span style="color: #89DDFF;">&gt;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">2</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;@livewireStyles</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">3</span><span style="color: #89DDFF;">&nbsp;&nbsp;&nbsp;&nbsp;&lt;</span><span style="color: #F07178;">script</span><span style="color: #89DDFF;"> </span><span style="color: #C792EA;">defer</span><span style="color: #89DDFF;"> </span><span style="color: #C792EA;">src</span><span style="color: #89DDFF;">=</span><span style="color: #89DDFF;">&quot;</span><span style="color: #C3E88D;">https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js</span><span style="color: #89DDFF;">&quot;</span><span style="color: #89DDFF;">&gt;&lt;/</span><span style="color: #F07178;">script</span><span style="color: #89DDFF;">&gt;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">4</span><span style="color: #89DDFF;">&lt;/</span><span style="color: #F07178;">head</span><span style="color: #89DDFF;">&gt;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">5</span><span style="color: #89DDFF;">&lt;</span><span style="color: #F07178;">body</span><span style="color: #89DDFF;">&gt;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">6</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;{{ $slot }}</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">7</span>&nbsp;</div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">8</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;@livewireScripts</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">9</span><span style="color: #89DDFF;">&lt;/</span><span style="color: #F07178;">body</span><span style="color: #89DDFF;">&gt;</span></div></code></pre>
<blockquote>
<p>Note that I am using the tailwind play cdn. I recommend replacing this with tailwind that is actually compiled with either vite or laravel mix.</p>
</blockquote>
<p>Add this routes to web.php</p>
<pre><code data-theme="material-theme-palenight" data-lang="text" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">1</span><span style="color: #A6ACCD;">Route::get(&#39;file-uploader&#39;, \App\Http\Livewire\FileUploader::class)</span></div></code></pre>
<p>Open <code>/resources/views/livewire/file-uploader.blade.php</code> and paste this html into it</p>
<pre><code data-theme="material-theme-palenight" data-lang="html" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 1</span><span style="color: #89DDFF;">&lt;</span><span style="color: #F07178;">div</span><span style="color: #89DDFF;">&gt;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 2</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">&lt;</span><span style="color: #F07178;">div</span><span style="color: #89DDFF;"> </span><span style="color: #C792EA;">class</span><span style="color: #89DDFF;">=</span><span style="color: #89DDFF;">&quot;</span><span style="color: #C3E88D;">flex flex-col items-center justify-center h-screen bg-slate-200</span><span style="color: #89DDFF;">&quot;</span><span style="color: #89DDFF;">&gt;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 3</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">&lt;</span><span style="color: #F07178;">label</span><span style="color: #89DDFF;"> </span><span style="color: #C792EA;">class</span><span style="color: #89DDFF;">=</span><span style="color: #89DDFF;">&quot;</span><span style="color: #C3E88D;">flex flex-col items-center justify-center w-1/2 bg-white border shadow cursor-pointer h-1/2 rounded-2xl hover:bg-slate-50</span><span style="color: #89DDFF;">&quot;</span><span style="color: #89DDFF;">  </span><span style="color: #C792EA;">for</span><span style="color: #89DDFF;">=</span><span style="color: #89DDFF;">&quot;</span><span style="color: #C3E88D;">file-upload</span><span style="color: #89DDFF;">&quot;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 4</span><span style="color: #89DDFF;">  &gt;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 5</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">&lt;</span><span style="color: #F07178;">h3</span><span style="color: #89DDFF;"> </span><span style="color: #C792EA;">class</span><span style="color: #89DDFF;">=</span><span style="color: #89DDFF;">&quot;</span><span style="color: #C3E88D;">text-3xl</span><span style="color: #89DDFF;">&quot;</span><span style="color: #89DDFF;">&gt;</span><span style="color: #A6ACCD;">Click here to select files to upload</span><span style="color: #89DDFF;">&lt;/</span><span style="color: #F07178;">h3</span><span style="color: #89DDFF;">&gt;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 6</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">&lt;</span><span style="color: #F07178;">em</span><span style="color: #89DDFF;"> </span><span style="color: #C792EA;">class</span><span style="color: #89DDFF;">=</span><span style="color: #89DDFF;">&quot;</span><span style="color: #C3E88D;">italic text-slate-400</span><span style="color: #89DDFF;">&quot;</span><span style="color: #89DDFF;">&gt;</span><span style="color: #A6ACCD;">(Or drag files to the page)</span><span style="color: #89DDFF;">&lt;/</span><span style="color: #F07178;">em</span><span style="color: #89DDFF;">&gt;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 7</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">&lt;/</span><span style="color: #F07178;">label</span><span style="color: #89DDFF;">&gt;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 8</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">&lt;</span><span style="color: #F07178;">input</span><span style="color: #89DDFF;"> </span><span style="color: #C792EA;">type</span><span style="color: #89DDFF;">=</span><span style="color: #89DDFF;">&quot;</span><span style="color: #C3E88D;">file</span><span style="color: #89DDFF;">&quot;</span><span style="color: #89DDFF;"> </span><span style="color: #C792EA;">id</span><span style="color: #89DDFF;">=</span><span style="color: #89DDFF;">&quot;</span><span style="color: #C3E88D;">file-upload</span><span style="color: #89DDFF;">&quot;</span><span style="color: #89DDFF;"> </span><span style="color: #C792EA;">multiple</span><span style="color: #89DDFF;"> </span><span style="color: #C792EA;">class</span><span style="color: #89DDFF;">=</span><span style="color: #89DDFF;">&quot;</span><span style="color: #C3E88D;">hidden</span><span style="color: #89DDFF;">&quot;</span><span style="color: #89DDFF;"> /&gt;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 9</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">&lt;/</span><span style="color: #F07178;">div</span><span style="color: #89DDFF;">&gt;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">10</span><span style="color: #89DDFF;">&lt;/</span><span style="color: #F07178;">div</span><span style="color: #89DDFF;">&gt;</span></div></code></pre>
<p>This will give us a simple layout with a huge &quot;button&quot; that lets us click it to select the files to upload. This works by using a label as the container, and linking it to a hidden file input.</p>
<h2>Getting upload working</h2>
<p>To make our code a bit cleaner we will add a script tag inside the page to set up the data for alpine first. It will just return an object with some defaults we will use later. Add <code>x-data=&quot;fileUpload()&quot;</code> to the outermost div, and add the script shown below. Be sure to nest it inside the outermost div, as livewire does not like multiple root elements.</p>
<pre><code data-theme="material-theme-palenight" data-lang="html" class='torchlight has-focus-lines' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 1</span><span style="color: #89DDFF;">&lt;</span><span style="color: #F07178;">div</span><span style="color: #89DDFF;"> </span><span style="color: #C792EA;">x-data</span><span style="color: #89DDFF;">=</span><span style="color: #89DDFF;">&quot;</span><span style="color: #C3E88D;">fileUpload()</span><span style="color: #89DDFF;">&quot;</span><span style="color: #89DDFF;">&gt;</span><span style="color: #A6ACCD;">  </span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 2</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">&lt;</span><span style="color: #F07178;">div</span><span style="color: #89DDFF;"> </span><span style="color: #C792EA;">class</span><span style="color: #89DDFF;">=</span><span style="color: #89DDFF;">&quot;</span><span style="color: #C3E88D;">flex flex-col items-center justify-center h-screen bg-slate-200</span><span style="color: #89DDFF;">&quot;</span><span style="color: #89DDFF;">&gt;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 3</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">&lt;</span><span style="color: #F07178;">label</span><span style="color: #89DDFF;"> </span><span style="color: #C792EA;">class</span><span style="color: #89DDFF;">=</span><span style="color: #89DDFF;">&quot;</span><span style="color: #C3E88D;">flex flex-col items-center justify-center w-1/2 bg-white border shadow cursor-pointer h-1/2 rounded-2xl hover:bg-slate-50</span><span style="color: #89DDFF;">&quot;</span><span style="color: #89DDFF;">  </span><span style="color: #C792EA;">for</span><span style="color: #89DDFF;">=</span><span style="color: #89DDFF;">&quot;</span><span style="color: #C3E88D;">file-upload</span><span style="color: #89DDFF;">&quot;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 4</span><span style="color: #89DDFF;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&gt;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 5</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">&lt;</span><span style="color: #F07178;">h3</span><span style="color: #89DDFF;"> </span><span style="color: #C792EA;">class</span><span style="color: #89DDFF;">=</span><span style="color: #89DDFF;">&quot;</span><span style="color: #C3E88D;">text-3xl</span><span style="color: #89DDFF;">&quot;</span><span style="color: #89DDFF;">&gt;</span><span style="color: #A6ACCD;">Click here to select files to upload</span><span style="color: #89DDFF;">&lt;/</span><span style="color: #F07178;">h3</span><span style="color: #89DDFF;">&gt;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 6</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">&lt;</span><span style="color: #F07178;">em</span><span style="color: #89DDFF;"> </span><span style="color: #C792EA;">class</span><span style="color: #89DDFF;">=</span><span style="color: #89DDFF;">&quot;</span><span style="color: #C3E88D;">italic text-slate-400</span><span style="color: #89DDFF;">&quot;</span><span style="color: #89DDFF;">&gt;</span><span style="color: #A6ACCD;">(Or drag files to the page)</span><span style="color: #89DDFF;">&lt;/</span><span style="color: #F07178;">em</span><span style="color: #89DDFF;">&gt;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 7</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">&lt;/</span><span style="color: #F07178;">label</span><span style="color: #89DDFF;">&gt;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 8</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">&lt;</span><span style="color: #F07178;">input</span><span style="color: #89DDFF;"> </span><span style="color: #C792EA;">type</span><span style="color: #89DDFF;">=</span><span style="color: #89DDFF;">&quot;</span><span style="color: #C3E88D;">file</span><span style="color: #89DDFF;">&quot;</span><span style="color: #89DDFF;"> </span><span style="color: #C792EA;">id</span><span style="color: #89DDFF;">=</span><span style="color: #89DDFF;">&quot;</span><span style="color: #C3E88D;">file-upload</span><span style="color: #89DDFF;">&quot;</span><span style="color: #89DDFF;"> </span><span style="color: #C792EA;">multiple</span><span style="color: #89DDFF;"> </span><span style="color: #C792EA;">class</span><span style="color: #89DDFF;">=</span><span style="color: #89DDFF;">&quot;</span><span style="color: #C3E88D;">hidden</span><span style="color: #89DDFF;">&quot;</span><span style="color: #89DDFF;"> /&gt;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 9</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">&lt;/</span><span style="color: #F07178;">div</span><span style="color: #89DDFF;">&gt;</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">10</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp; </span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">11</span><span style="color: #89DDFF;">&nbsp;&nbsp;&nbsp;&nbsp;&lt;</span><span style="color: #F07178;">script</span><span style="color: #89DDFF;">&gt;</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">12</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #C792EA;">function</span><span style="color: #A6ACCD;"> </span><span style="color: #82AAFF;">fileUpload</span><span style="color: #89DDFF;">()</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">{</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">13</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">return</span><span style="color: #F07178;"> </span><span style="color: #89DDFF;">{</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">14</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;isDropping</span><span style="color: #89DDFF;">:</span><span style="color: #F07178;"> </span><span style="color: #FF9CAC;">false</span><span style="color: #89DDFF;">,</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">15</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;isUploading</span><span style="color: #89DDFF;">:</span><span style="color: #F07178;"> </span><span style="color: #FF9CAC;">false</span><span style="color: #89DDFF;">,</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">16</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;progress</span><span style="color: #89DDFF;">:</span><span style="color: #F07178;"> </span><span style="color: #F78C6C;">0</span><span style="color: #89DDFF;">,</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">17</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">}</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">18</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">}</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">19</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">&lt;/</span><span style="color: #F07178;">script</span><span style="color: #89DDFF;">&gt;</span><span style="color: #A6ACCD;"> </span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">20</span><span style="color: #89DDFF;">&lt;/</span><span style="color: #F07178;">div</span><span style="color: #89DDFF;">&gt;</span></div></code></pre>
<p>Normally when you add a file input to the page with livewire, you would simply use <code>wire:model</code> to automatically upload the files as they are added (to a temp directory). But as we need to implement the upload when dragging files, it makes sense to implement this ourselves as well. Luckily livewire makes this very simple.</p>
<p>Add a new function inside the returned object in the script</p>
<pre><code data-theme="material-theme-palenight" data-lang="javascript" class='torchlight has-focus-lines' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 1</span><span style="color: #89DDFF;">&lt;</span><span style="color: #F07178;">script</span><span style="color: #89DDFF;">&gt;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 2</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;function fileUpload() </span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 3</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return </span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 4</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">isDropping</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #FF9CAC;">false</span><span style="color: #89DDFF;">,</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 5</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">isUploading</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #FF9CAC;">false</span><span style="color: #89DDFF;">,</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 6</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">progress</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">0</span><span style="color: #89DDFF;">,</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 7</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">handleFileSelect</span><span style="color: #89DDFF;">(</span><span style="color: #A6ACCD;">event</span><span style="color: #89DDFF;">)</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">{</span><span style="color: #F07178;"> </span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 8</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">if</span><span style="color: #F07178;"> (</span><span style="color: #A6ACCD;">event</span><span style="color: #89DDFF;">.</span><span style="color: #A6ACCD;">target</span><span style="color: #89DDFF;">.</span><span style="color: #A6ACCD;">files</span><span style="color: #89DDFF;">.</span><span style="color: #A6ACCD;">length</span><span style="color: #F07178;">) </span><span style="color: #89DDFF;">{</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 9</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #A6ACCD;">console</span><span style="color: #89DDFF;">.</span><span style="color: #82AAFF;">log</span><span style="color: #F07178;">(</span><span style="color: #A6ACCD;">event</span><span style="color: #89DDFF;">.</span><span style="color: #A6ACCD;">target</span><span style="color: #89DDFF;">.</span><span style="color: #A6ACCD;">files</span><span style="color: #F07178;">)</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">10</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">}</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">11</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">},</span><span style="color: #A6ACCD;"> </span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">12</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">}</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">13</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">}</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">14</span><span style="color: #89DDFF;">&lt;/</span><span style="color: #F07178;">script</span><span style="color: #89DDFF;">&gt;</span></div></code></pre>
<p>and add the script to the file inputs <code>@change</code> hook</p>
<pre><code data-theme="material-theme-palenight" data-lang="html" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">1</span><span style="color: #89DDFF;">&lt;</span><span style="color: #F07178;">input</span><span style="color: #89DDFF;"> </span><span style="color: #C792EA;">type</span><span style="color: #89DDFF;">=</span><span style="color: #89DDFF;">&quot;</span><span style="color: #C3E88D;">file</span><span style="color: #89DDFF;">&quot;</span><span style="color: #89DDFF;"> </span><span style="color: #C792EA;">id</span><span style="color: #89DDFF;">=</span><span style="color: #89DDFF;">&quot;</span><span style="color: #C3E88D;">file-upload</span><span style="color: #89DDFF;">&quot;</span><span style="color: #89DDFF;"> </span><span style="color: #C792EA;">multiple</span><span style="color: #89DDFF;"> </span><span style="color: #C792EA;">@change</span><span style="color: #89DDFF;">=</span><span style="color: #89DDFF;">&quot;</span><span style="color: #C3E88D;">handleFileSelect</span><span style="color: #89DDFF;">&quot;</span><span style="color: #89DDFF;"> </span><span style="color: #C792EA;">class</span><span style="color: #89DDFF;">=</span><span style="color: #89DDFF;">&quot;</span><span style="color: #C3E88D;">hidden</span><span style="color: #89DDFF;">&quot;</span><span style="color: #89DDFF;"> /&gt;</span></div></code></pre>
<p>Now try clicking the button and select a file. Open the browser console (F12) and you should see a log of the file being added.</p>
<p>Now for the actual upload.</p>
<p>First we will add the <code>WithFileUploads</code> trait to the component to tell livewire that we want file uploads. Next we add a new public property to the component class to have a place for livewire to store a reference to the files.</p>
<pre><code data-theme="material-theme-palenight" data-lang="php" class='torchlight has-focus-lines' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 1</span><span style="color: #89DDFF;">&lt;?php</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 2</span>&nbsp;</div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 3</span><span style="color: #F78C6C;">namespace</span><span style="color: #A6ACCD;"> </span><span style="color: #FFCB6B;">App</span><span style="color: #89DDFF;">\</span><span style="color: #FFCB6B;">Http</span><span style="color: #89DDFF;">\</span><span style="color: #FFCB6B;">Livewire</span><span style="color: #89DDFF;">;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 4</span>&nbsp;</div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 5</span><span style="color: #F78C6C;">use</span><span style="color: #FFCB6B;"> </span><span style="color: #A6ACCD;">Livewire</span><span style="color: #89DDFF;">\</span><span style="color: #A6ACCD;">Component</span><span style="color: #89DDFF;">;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 6</span><span style="color: #F78C6C;">use</span><span style="color: #FFCB6B;"> </span><span style="color: #A6ACCD;">Livewire</span><span style="color: #89DDFF;">\</span><span style="color: #A6ACCD;">WithFileUploads</span><span style="color: #89DDFF;">;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 7</span>&nbsp;</div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 8</span><span style="color: #C792EA;">class</span><span style="color: #A6ACCD;"> </span><span style="color: #FFCB6B;">FileUploader</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">extends</span><span style="color: #A6ACCD;"> </span><span style="color: #FFCB6B;">Component</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 9</span><span style="color: #89DDFF;">{</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">10</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F78C6C;">use</span><span style="color: #FFCB6B;"> </span><span style="color: #A6ACCD;">WithFileUploads</span><span style="color: #89DDFF;">;</span><span style="color: #A6ACCD;"> </span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">11</span>&nbsp;</div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">12</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #C792EA;">public</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">files </span><span style="color: #89DDFF;">=</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">[];</span><span style="color: #A6ACCD;"> </span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">13</span>&nbsp;</div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">14</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #C792EA;">public</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">function</span><span style="color: #A6ACCD;"> </span><span style="color: #82AAFF;">render</span><span style="color: #89DDFF;">()</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">15</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">16</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">return</span><span style="color: #A6ACCD;"> </span><span style="color: #82AAFF;">view</span><span style="color: #89DDFF;">(</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">livewire.file-uploader</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">);</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">17</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">}</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">18</span><span style="color: #89DDFF;">}</span></div></code></pre>
<p>Livewire has a few handle built in helpers for uploading files which we can use. <a href="https://laravel-livewire.com/docs/2.x/file-uploads#js-api">https://laravel-livewire.com/docs/2.x/file-uploads#js-api</a></p>
<p>So we add a new method to handle all uploads called <code>uploadFiles()</code>. It receives the files and uses the livewire <code>@this.uploadMultiple()</code> function to upload them to the livewire component. Note that the first argument is the name of the public property in the component class. Not that I am rebinding <code>this</code> to <code>$this</code>. This is because the <code>this</code> changes when inside the functions of each callback in the upload. This could also be handled by using <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions">arrow functions</a></p>
<pre><code data-theme="material-theme-palenight" data-lang="js" class='torchlight has-focus-lines' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 1</span><span style="color: #89DDFF;">&lt;</span><span style="color: #F07178;">script</span><span style="color: #89DDFF;">&gt;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 2</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;function fileUpload() </span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 3</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return </span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 4</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">isDropping</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #FF9CAC;">false</span><span style="color: #89DDFF;">,</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 5</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">isUploading</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #FF9CAC;">false</span><span style="color: #89DDFF;">,</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 6</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">progress</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">0</span><span style="color: #89DDFF;">,</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 7</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">handleFileSelect</span><span style="color: #89DDFF;">(</span><span style="color: #A6ACCD;">event</span><span style="color: #89DDFF;">)</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">{</span><span style="color: #F07178;">  </span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 8</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">if</span><span style="color: #F07178;"> (</span><span style="color: #A6ACCD;">event</span><span style="color: #89DDFF;">.</span><span style="color: #A6ACCD;">target</span><span style="color: #89DDFF;">.</span><span style="color: #A6ACCD;">files</span><span style="color: #89DDFF;">.</span><span style="color: #A6ACCD;">length</span><span style="color: #F07178;">) </span><span style="color: #89DDFF;">{</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 9</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">this.</span><span style="color: #82AAFF;">uploadFiles</span><span style="color: #F07178;">(</span><span style="color: #A6ACCD;">event</span><span style="color: #89DDFF;">.</span><span style="color: #A6ACCD;">target</span><span style="color: #89DDFF;">.</span><span style="color: #A6ACCD;">files</span><span style="color: #F07178;">)</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">10</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">}</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">11</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">},</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">12</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">uploadFiles</span><span style="color: #89DDFF;">(</span><span style="color: #A6ACCD;">files</span><span style="color: #89DDFF;">)</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">{</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">13</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #C792EA;">const</span><span style="color: #F07178;"> </span><span style="color: #A6ACCD;">$this</span><span style="color: #F07178;"> </span><span style="color: #89DDFF;">=</span><span style="color: #F07178;"> </span><span style="color: #89DDFF;">this</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">14</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">this.</span><span style="color: #A6ACCD;">isUploading</span><span style="color: #F07178;"> </span><span style="color: #89DDFF;">=</span><span style="color: #F07178;"> </span><span style="color: #FF9CAC;">true</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">15</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">@this.</span><span style="color: #82AAFF;">uploadMultiple</span><span style="color: #F07178;">(</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">files</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">,</span><span style="color: #F07178;"> </span><span style="color: #A6ACCD;">files</span><span style="color: #89DDFF;">,</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">16</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #C792EA;">function</span><span style="color: #F07178;"> </span><span style="color: #89DDFF;">(</span><span style="color: #A6ACCD;">success</span><span style="color: #89DDFF;">)</span><span style="color: #F07178;"> </span><span style="color: #89DDFF;">{</span><span style="color: #F07178;">  </span><span style="color: #676E95;">//upload was a success and was finished</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">17</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #A6ACCD;">$this</span><span style="color: #89DDFF;">.</span><span style="color: #A6ACCD;">isUploading</span><span style="color: #F07178;"> </span><span style="color: #89DDFF;">=</span><span style="color: #F07178;"> </span><span style="color: #FF9CAC;">false</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">18</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #A6ACCD;">$this</span><span style="color: #89DDFF;">.</span><span style="color: #A6ACCD;">progress</span><span style="color: #F07178;"> </span><span style="color: #89DDFF;">=</span><span style="color: #F07178;"> </span><span style="color: #F78C6C;">0</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">19</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">},</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">20</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #C792EA;">function</span><span style="color: #89DDFF;">(</span><span style="color: #A6ACCD;">error</span><span style="color: #89DDFF;">)</span><span style="color: #F07178;"> </span><span style="color: #89DDFF;">{</span><span style="color: #F07178;">  </span><span style="color: #676E95;">//an error occured</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">21</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #A6ACCD;">console</span><span style="color: #89DDFF;">.</span><span style="color: #82AAFF;">log</span><span style="color: #F07178;">(</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">error</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">,</span><span style="color: #F07178;"> </span><span style="color: #A6ACCD;">error</span><span style="color: #F07178;">)</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">22</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">},</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">23</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #C792EA;">function</span><span style="color: #F07178;"> </span><span style="color: #89DDFF;">(</span><span style="color: #A6ACCD;">event</span><span style="color: #89DDFF;">)</span><span style="color: #F07178;"> </span><span style="color: #89DDFF;">{</span><span style="color: #F07178;">  </span><span style="color: #676E95;">//upload progress was made</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">24</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #A6ACCD;">$this</span><span style="color: #89DDFF;">.</span><span style="color: #A6ACCD;">progress</span><span style="color: #F07178;"> </span><span style="color: #89DDFF;">=</span><span style="color: #F07178;"> </span><span style="color: #A6ACCD;">event</span><span style="color: #89DDFF;">.</span><span style="color: #A6ACCD;">detail</span><span style="color: #89DDFF;">.</span><span style="color: #A6ACCD;">progress</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">25</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">}</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">26</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">27</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">}</span><span style="color: #A6ACCD;"> </span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">28</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">}</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">29</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">}</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">30</span><span style="color: #89DDFF;">&lt;/</span><span style="color: #F07178;">script</span><span style="color: #89DDFF;">&gt;</span></div></code></pre>
<p>First we set the upload to have started with <code>this.isUploading = true</code>. We then update the other attributes based on the upload status.</p>
<p>Now before we test it out, it might be nice to be able to see the files, so let us update the view to show them. Lets add some code right after the <code>&lt;label&gt;</code> to show the files</p>
<pre><code data-theme="material-theme-palenight" data-lang="html" class='torchlight has-focus-lines' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 1</span><span style="color: #89DDFF;">&lt;</span><span style="color: #F07178;">label</span><span style="color: #89DDFF;"> </span><span style="color: #C792EA;">class</span><span style="color: #89DDFF;">=</span><span style="color: #89DDFF;">&quot;</span><span style="color: #C3E88D;">flex flex-col items-center justify-center w-1/2 bg-white border shadow cursor-pointer h-1/2 rounded-2xl hover:bg-slate-50</span><span style="color: #89DDFF;">&quot;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 2</span><span style="color: #89DDFF;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #C792EA;">for</span><span style="color: #89DDFF;">=</span><span style="color: #89DDFF;">&quot;</span><span style="color: #C3E88D;">file-upload</span><span style="color: #89DDFF;">&quot;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 3</span><span style="color: #89DDFF;">&gt;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 4</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">&lt;</span><span style="color: #F07178;">h3</span><span style="color: #89DDFF;"> </span><span style="color: #C792EA;">class</span><span style="color: #89DDFF;">=</span><span style="color: #89DDFF;">&quot;</span><span style="color: #C3E88D;">text-3xl</span><span style="color: #89DDFF;">&quot;</span><span style="color: #89DDFF;">&gt;</span><span style="color: #A6ACCD;">Click here to select files to upload</span><span style="color: #89DDFF;">&lt;/</span><span style="color: #F07178;">h3</span><span style="color: #89DDFF;">&gt;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 5</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">&lt;</span><span style="color: #F07178;">em</span><span style="color: #89DDFF;"> </span><span style="color: #C792EA;">class</span><span style="color: #89DDFF;">=</span><span style="color: #89DDFF;">&quot;</span><span style="color: #C3E88D;">italic text-slate-400</span><span style="color: #89DDFF;">&quot;</span><span style="color: #89DDFF;">&gt;</span><span style="color: #A6ACCD;">(Or drag files to the page)</span><span style="color: #89DDFF;">&lt;/</span><span style="color: #F07178;">em</span><span style="color: #89DDFF;">&gt;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 6</span><span style="color: #89DDFF;">&lt;/</span><span style="color: #F07178;">label</span><span style="color: #89DDFF;">&gt;</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 7</span><span style="color: #A6ACCD;"> @if(count($files)) </span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 8</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">&lt;</span><span style="color: #F07178;">ul</span><span style="color: #89DDFF;"> </span><span style="color: #C792EA;">class</span><span style="color: #89DDFF;">=</span><span style="color: #89DDFF;">&quot;</span><span style="color: #C3E88D;">mt-5 list-disc</span><span style="color: #89DDFF;">&quot;</span><span style="color: #89DDFF;">&gt;</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 9</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@foreach($files as $file)</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">10</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">&lt;</span><span style="color: #F07178;">li</span><span style="color: #89DDFF;">&gt;</span><span style="color: #A6ACCD;">{{$file-&gt;getClientOriginalName()}}</span><span style="color: #89DDFF;">&lt;/</span><span style="color: #F07178;">li</span><span style="color: #89DDFF;">&gt;</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">11</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@endforeach</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">12</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">&lt;/</span><span style="color: #F07178;">ul</span><span style="color: #89DDFF;">&gt;</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">13</span><span style="color: #A6ACCD;">@endif </span></div></code></pre>
<p>Now try selecting a file again, and this time you should see the file names show up in a list.</p>
<h2>Dropping files</h2>
<p>Dropping of files is actually quite easy to implement now that we have the regular upload working. First we will add a function similar to the one used for file selection.</p>
<pre><code data-theme="material-theme-palenight" data-lang="js" class='torchlight has-focus-lines' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 1</span><span style="color: #89DDFF;">&lt;</span><span style="color: #F07178;">script</span><span style="color: #89DDFF;">&gt;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 2</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;function fileUpload() </span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 3</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return </span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 4</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">isDropping</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #FF9CAC;">false</span><span style="color: #89DDFF;">,</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 5</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">isUploading</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #FF9CAC;">false</span><span style="color: #89DDFF;">,</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 6</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">progress</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">0</span><span style="color: #89DDFF;">,</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 7</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">handleFileSelect</span><span style="color: #89DDFF;">(</span><span style="color: #A6ACCD;">event</span><span style="color: #89DDFF;">)</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 8</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">if</span><span style="color: #F07178;"> (</span><span style="color: #A6ACCD;">event</span><span style="color: #89DDFF;">.</span><span style="color: #A6ACCD;">target</span><span style="color: #89DDFF;">.</span><span style="color: #A6ACCD;">files</span><span style="color: #89DDFF;">.</span><span style="color: #A6ACCD;">length</span><span style="color: #F07178;">) </span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 9</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">this.</span><span style="color: #82AAFF;">uploadFiles</span><span style="color: #F07178;">(</span><span style="color: #A6ACCD;">event</span><span style="color: #89DDFF;">.</span><span style="color: #A6ACCD;">target</span><span style="color: #89DDFF;">.</span><span style="color: #A6ACCD;">files</span><span style="color: #F07178;">)</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">10</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">}</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">11</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">},</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">12</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">handleFileDrop</span><span style="color: #89DDFF;">(</span><span style="color: #A6ACCD;">event</span><span style="color: #89DDFF;">)</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">{</span><span style="color: #F07178;"> </span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">13</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">if</span><span style="color: #F07178;"> (</span><span style="color: #A6ACCD;">event</span><span style="color: #89DDFF;">.</span><span style="color: #A6ACCD;">dataTransfer</span><span style="color: #89DDFF;">.</span><span style="color: #A6ACCD;">files</span><span style="color: #89DDFF;">.</span><span style="color: #A6ACCD;">length</span><span style="color: #F07178;"> </span><span style="color: #89DDFF;">&gt;</span><span style="color: #F07178;"> </span><span style="color: #F78C6C;">0</span><span style="color: #F07178;">) </span><span style="color: #89DDFF;">{</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">14</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">this.</span><span style="color: #82AAFF;">uploadFiles</span><span style="color: #F07178;">(</span><span style="color: #A6ACCD;">event</span><span style="color: #89DDFF;">.</span><span style="color: #A6ACCD;">dataTransfer</span><span style="color: #89DDFF;">.</span><span style="color: #A6ACCD;">files</span><span style="color: #F07178;">)</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">15</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">}</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">16</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">},</span><span style="color: #A6ACCD;"> </span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">17</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">uploadFiles</span><span style="color: #89DDFF;">(</span><span style="color: #A6ACCD;">files</span><span style="color: #89DDFF;">)</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">18</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #C792EA;">const</span><span style="color: #F07178;"> </span><span style="color: #A6ACCD;">$this</span><span style="color: #F07178;"> </span><span style="color: #89DDFF;">=</span><span style="color: #F07178;"> </span><span style="color: #89DDFF;">this;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">19</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">this.</span><span style="color: #A6ACCD;">isUploading</span><span style="color: #F07178;"> </span><span style="color: #89DDFF;">=</span><span style="color: #F07178;"> </span><span style="color: #FF9CAC;">true</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">20</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">@this.</span><span style="color: #82AAFF;">uploadMultiple</span><span style="color: #F07178;">(</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">files</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">,</span><span style="color: #F07178;"> </span><span style="color: #A6ACCD;">files</span><span style="color: #89DDFF;">,</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">21</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #C792EA;">function</span><span style="color: #F07178;"> </span><span style="color: #89DDFF;">(</span><span style="color: #A6ACCD;">success</span><span style="color: #89DDFF;">)</span><span style="color: #F07178;"> </span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">22</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #A6ACCD;">$this</span><span style="color: #89DDFF;">.</span><span style="color: #A6ACCD;">isUploading</span><span style="color: #F07178;"> </span><span style="color: #89DDFF;">=</span><span style="color: #F07178;"> </span><span style="color: #FF9CAC;">false</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">23</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #A6ACCD;">$this</span><span style="color: #89DDFF;">.</span><span style="color: #A6ACCD;">progress</span><span style="color: #F07178;"> </span><span style="color: #89DDFF;">=</span><span style="color: #F07178;"> </span><span style="color: #F78C6C;">0</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">24</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">},</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">25</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #C792EA;">function</span><span style="color: #89DDFF;">(</span><span style="color: #A6ACCD;">error</span><span style="color: #89DDFF;">)</span><span style="color: #F07178;"> </span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">26</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #A6ACCD;">console</span><span style="color: #89DDFF;">.</span><span style="color: #82AAFF;">log</span><span style="color: #F07178;">(</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">error</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">,</span><span style="color: #F07178;"> </span><span style="color: #A6ACCD;">error</span><span style="color: #F07178;">)</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">27</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">},</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">28</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #C792EA;">function</span><span style="color: #F07178;"> </span><span style="color: #89DDFF;">(</span><span style="color: #A6ACCD;">event</span><span style="color: #89DDFF;">)</span><span style="color: #F07178;"> </span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">29</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #A6ACCD;">$this</span><span style="color: #89DDFF;">.</span><span style="color: #A6ACCD;">progress</span><span style="color: #F07178;"> </span><span style="color: #89DDFF;">=</span><span style="color: #F07178;"> </span><span style="color: #A6ACCD;">event</span><span style="color: #89DDFF;">.</span><span style="color: #A6ACCD;">detail</span><span style="color: #89DDFF;">.</span><span style="color: #A6ACCD;">progress</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">30</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">}</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">31</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">32</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">}</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">33</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">}</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">34</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">}</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">35</span><span style="color: #89DDFF;">&lt;/</span><span style="color: #F07178;">script</span><span style="color: #89DDFF;">&gt;</span></div></code></pre>
<p>Next we will let the whole page accept file drops. Luckily AlpineJs has built in checks for file drops, so it is very easy add.</p>
<pre><code data-theme="material-theme-palenight" data-lang="html" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">1</span><span style="color: #89DDFF;">&lt;</span><span style="color: #F07178;">div</span><span style="color: #89DDFF;"> </span><span style="color: #C792EA;">x-data</span><span style="color: #89DDFF;">=</span><span style="color: #89DDFF;">&quot;</span><span style="color: #C3E88D;">fileUpload()</span><span style="color: #89DDFF;">&quot;</span><span style="color: #89DDFF;">&gt;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">2</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">&lt;</span><span style="color: #F07178;">div</span><span style="color: #89DDFF;"> </span><span style="color: #C792EA;">class</span><span style="color: #89DDFF;">=</span><span style="color: #89DDFF;">&quot;</span><span style="color: #C3E88D;">flex flex-col items-center justify-center h-screen bg-slate-200</span><span style="color: #89DDFF;">&quot;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">3</span><span style="color: #89DDFF;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #C792EA;">x-on:drop</span><span style="color: #89DDFF;">=</span><span style="color: #89DDFF;">&quot;</span><span style="color: #C3E88D;">isDroppingFile = false</span><span style="color: #89DDFF;">&quot;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">4</span><span style="color: #89DDFF;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #C792EA;">x-on:drop.prevent</span><span style="color: #89DDFF;">=</span><span style="color: #89DDFF;">&quot;</span><span style="color: #C3E88D;">handleFileDrop($event)</span><span style="color: #89DDFF;">&quot;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">5</span><span style="color: #89DDFF;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #C792EA;">x-on:dragover.prevent</span><span style="color: #89DDFF;">=</span><span style="color: #89DDFF;">&quot;</span><span style="color: #C3E88D;">isDroppingFile = true</span><span style="color: #89DDFF;">&quot;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">6</span><span style="color: #89DDFF;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #C792EA;">x-on:dragleave.prevent</span><span style="color: #89DDFF;">=</span><span style="color: #89DDFF;">&quot;</span><span style="color: #C3E88D;">isDroppingFile = false</span><span style="color: #89DDFF;">&quot;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">7</span><span style="color: #89DDFF;">&nbsp;&nbsp;&nbsp;&nbsp;&gt;</span></div></code></pre>
<p>Now drag a file onto the page, and it should just work!</p>
<p>For the sake of completion, lets just add a quick overlay on the page so its obvious we are inside the drop zone.</p>
<pre><code data-theme="material-theme-palenight" data-lang="html" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 1</span><span style="color: #89DDFF;">&lt;</span><span style="color: #F07178;">div</span><span style="color: #89DDFF;"> </span><span style="color: #C792EA;">x-data</span><span style="color: #89DDFF;">=</span><span style="color: #89DDFF;">&quot;</span><span style="color: #C3E88D;">fileUpload()</span><span style="color: #89DDFF;">&quot;</span><span style="color: #89DDFF;">&gt;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 2</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">&lt;</span><span style="color: #F07178;">div</span><span style="color: #89DDFF;"> </span><span style="color: #C792EA;">class</span><span style="color: #89DDFF;">=</span><span style="color: #89DDFF;">&quot;</span><span style="color: #C3E88D;">relative flex flex-col items-center justify-center h-screen bg-slate-200</span><span style="color: #89DDFF;">&quot;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 3</span><span style="color: #89DDFF;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #C792EA;">x-on:drop</span><span style="color: #89DDFF;">=</span><span style="color: #89DDFF;">&quot;</span><span style="color: #C3E88D;">isDropping = false</span><span style="color: #89DDFF;">&quot;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 4</span><span style="color: #89DDFF;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #C792EA;">x-on:drop.prevent</span><span style="color: #89DDFF;">=</span><span style="color: #89DDFF;">&quot;</span><span style="color: #C3E88D;">handleFileDrop($event)</span><span style="color: #89DDFF;">&quot;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 5</span><span style="color: #89DDFF;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #C792EA;">x-on:dragover.prevent</span><span style="color: #89DDFF;">=</span><span style="color: #89DDFF;">&quot;</span><span style="color: #C3E88D;">isDropping = true</span><span style="color: #89DDFF;">&quot;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 6</span><span style="color: #89DDFF;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #C792EA;">x-on:dragleave.prevent</span><span style="color: #89DDFF;">=</span><span style="color: #89DDFF;">&quot;</span><span style="color: #C3E88D;">isDropping = false</span><span style="color: #89DDFF;">&quot;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 7</span><span style="color: #89DDFF;">&nbsp;&nbsp;&nbsp;&nbsp;&gt;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 8</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">&lt;</span><span style="color: #F07178;">div</span><span style="color: #89DDFF;"> </span><span style="color: #C792EA;">class</span><span style="color: #89DDFF;">=</span><span style="color: #89DDFF;">&quot;</span><span style="color: #C3E88D;">absolute top-0 bottom-0 left-0 right-0 z-30 flex items-center justify-center bg-blue-500 opacity-90</span><span style="color: #89DDFF;">&quot;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 9</span><span style="color: #89DDFF;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #C792EA;">x-show</span><span style="color: #89DDFF;">=</span><span style="color: #89DDFF;">&quot;</span><span style="color: #C3E88D;">isDropping</span><span style="color: #89DDFF;">&quot;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">10</span><span style="color: #89DDFF;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&gt;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">11</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">&lt;</span><span style="color: #F07178;">span</span><span style="color: #89DDFF;"> </span><span style="color: #C792EA;">class</span><span style="color: #89DDFF;">=</span><span style="color: #89DDFF;">&quot;</span><span style="color: #C3E88D;">text-3xl text-white</span><span style="color: #89DDFF;">&quot;</span><span style="color: #89DDFF;">&gt;</span><span style="color: #A6ACCD;">Release file to upload!</span><span style="color: #89DDFF;">&lt;/</span><span style="color: #F07178;">span</span><span style="color: #89DDFF;">&gt;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">12</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">&lt;/</span><span style="color: #F07178;">div</span><span style="color: #89DDFF;">&gt;</span></div></code></pre>
<p>Here we add <code>relative</code> to the div that covers the page, and adds a simple overlay div that is shown whenever we are dragging over the page.</p>
<blockquote>
<p>I am aware that there is some flickering when the file is right on top of the text in the middle of the page. Sadly I have yet to find a solution for this. Let me know if you find a solution so I can update the guide. <a href="https://twitter.com/rsinnbeck">@rsinnbeck</a></p>
</blockquote>
<h2>Adding a progress bar</h2>
<p>To complete our file uploader, I think it would be great with a progress bar.</p>
<p>At the bottom of our <code>&lt;label&gt;</code> we can add a small bar that gets filled whenever we upload anything.</p>
<pre><code data-theme="material-theme-palenight" data-lang="html" class='torchlight has-focus-lines' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 1</span><span style="color: #89DDFF;">&lt;</span><span style="color: #F07178;">label</span><span style="color: #89DDFF;"> </span><span style="color: #C792EA;">class</span><span style="color: #89DDFF;">=</span><span style="color: #89DDFF;">&quot;</span><span style="color: #C3E88D;">flex flex-col items-center justify-center w-1/2 bg-white border shadow cursor-pointer select-none h-1/2 rounded-2xl hover:bg-slate-50</span><span style="color: #89DDFF;">&quot;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 2</span><span style="color: #89DDFF;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #C792EA;">for</span><span style="color: #89DDFF;">=</span><span style="color: #89DDFF;">&quot;</span><span style="color: #C3E88D;">file-upload</span><span style="color: #89DDFF;">&quot;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 3</span><span style="color: #89DDFF;">&gt;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 4</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">&lt;</span><span style="color: #F07178;">h3</span><span style="color: #89DDFF;"> </span><span style="color: #C792EA;">class</span><span style="color: #89DDFF;">=</span><span style="color: #89DDFF;">&quot;</span><span style="color: #C3E88D;">text-3xl</span><span style="color: #89DDFF;">&quot;</span><span style="color: #89DDFF;">&gt;</span><span style="color: #A6ACCD;">Click here to select files to upload</span><span style="color: #89DDFF;">&lt;/</span><span style="color: #F07178;">h3</span><span style="color: #89DDFF;">&gt;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 5</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">&lt;</span><span style="color: #F07178;">em</span><span style="color: #89DDFF;"> </span><span style="color: #C792EA;">class</span><span style="color: #89DDFF;">=</span><span style="color: #89DDFF;">&quot;</span><span style="color: #C3E88D;">italic text-slate-400</span><span style="color: #89DDFF;">&quot;</span><span style="color: #89DDFF;">&gt;</span><span style="color: #A6ACCD;">(Or drag files to the page)</span><span style="color: #89DDFF;">&lt;/</span><span style="color: #F07178;">em</span><span style="color: #89DDFF;">&gt;</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 6</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">&lt;</span><span style="color: #F07178;">div</span><span style="color: #89DDFF;"> </span><span style="color: #C792EA;">class</span><span style="color: #89DDFF;">=</span><span style="color: #89DDFF;">&quot;</span><span style="color: #C3E88D;">bg-gray-200 h-[2px] w-1/2 mt-3</span><span style="color: #89DDFF;">&quot;</span><span style="color: #89DDFF;">&gt;</span><span style="color: #A6ACCD;"> </span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 7</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">&lt;</span><span style="color: #F07178;">div</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 8</span><span style="color: #89DDFF;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #C792EA;">class</span><span style="color: #89DDFF;">=</span><span style="color: #89DDFF;">&quot;</span><span style="color: #C3E88D;">bg-blue-500 h-[2px]</span><span style="color: #89DDFF;">&quot;</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 9</span><span style="color: #89DDFF;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #C792EA;">style</span><span style="color: #89DDFF;">=</span><span style="color: #89DDFF;">&quot;</span><span style="color: #C3E88D;">transition: width 1s</span><span style="color: #89DDFF;">&quot;</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">10</span><span style="color: #89DDFF;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #C792EA;">:style</span><span style="color: #89DDFF;">=</span><span style="color: #89DDFF;">&quot;</span><span style="color: #C3E88D;">`width: ${progress}%;`</span><span style="color: #89DDFF;">&quot;</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">11</span><span style="color: #89DDFF;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #C792EA;">x-show</span><span style="color: #89DDFF;">=</span><span style="color: #89DDFF;">&quot;</span><span style="color: #C3E88D;">isUploading</span><span style="color: #89DDFF;">&quot;</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">12</span><span style="color: #89DDFF;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&gt;</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">13</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">&lt;/</span><span style="color: #F07178;">div</span><span style="color: #89DDFF;">&gt;</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">14</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">&lt;/</span><span style="color: #F07178;">div</span><span style="color: #89DDFF;">&gt;</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">15</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">16</span><span style="color: #89DDFF;">&lt;/</span><span style="color: #F07178;">label</span><span style="color: #89DDFF;">&gt;</span></div></code></pre>
<p>And just like that we can see the progress of the uploads!
Be aware that you might not be able to see the progress bar move at all, as the uploads are so fast when working locally. Therefor it might be a good idea to enable throttling in the browser, so you can actually see it progress: <a href="https://www.browserstack.com/guide/how-to-perform-network-throttling-in-chrome">https://www.browserstack.com/guide/how-to-perform-network-throttling-in-chrome</a></p>
<h2>Append uploads</h2>
<p>You might notice that if you add files in more than one go, it will replace all the files from earlier. This is due to the fact that, livewire just throws away old files when using <code>@this.uploadMultiple()</code>. Luckily we can just overwrite the upload function for this component to force it to merge the uploads.</p>
<p>Add a <code>finishUpload()</code> method to the component class</p>
<pre><code data-theme="material-theme-palenight" data-lang="php" class='torchlight has-focus-lines' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 1</span><span style="color: #89DDFF;">&lt;?php</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 2</span>&nbsp;</div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 3</span><span style="color: #F78C6C;">namespace</span><span style="color: #A6ACCD;"> </span><span style="color: #FFCB6B;">App</span><span style="color: #89DDFF;">\</span><span style="color: #FFCB6B;">Http</span><span style="color: #89DDFF;">\</span><span style="color: #FFCB6B;">Livewire</span><span style="color: #89DDFF;">;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 4</span>&nbsp;</div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 5</span><span style="color: #F78C6C;">use</span><span style="color: #FFCB6B;"> </span><span style="color: #A6ACCD;">Livewire</span><span style="color: #89DDFF;">\</span><span style="color: #A6ACCD;">Component</span><span style="color: #89DDFF;">;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 6</span><span style="color: #F78C6C;">use</span><span style="color: #FFCB6B;"> </span><span style="color: #A6ACCD;">Livewire</span><span style="color: #89DDFF;">\</span><span style="color: #A6ACCD;">TemporaryUploadedFile</span><span style="color: #89DDFF;">;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 7</span><span style="color: #F78C6C;">use</span><span style="color: #FFCB6B;"> </span><span style="color: #A6ACCD;">Livewire</span><span style="color: #89DDFF;">\</span><span style="color: #A6ACCD;">WithFileUploads</span><span style="color: #89DDFF;">;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 8</span>&nbsp;</div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 9</span><span style="color: #C792EA;">class</span><span style="color: #A6ACCD;"> </span><span style="color: #FFCB6B;">FileUploader</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">extends</span><span style="color: #A6ACCD;"> </span><span style="color: #FFCB6B;">Component</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">10</span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">11</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F78C6C;">use</span><span style="color: #FFCB6B;"> </span><span style="color: #A6ACCD;">WithFileUploads</span><span style="color: #89DDFF;">;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">12</span>&nbsp;</div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">13</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #C792EA;">public</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">files </span><span style="color: #89DDFF;">=</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">[];</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">14</span>&nbsp;</div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">15</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #C792EA;">public</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">function</span><span style="color: #A6ACCD;"> </span><span style="color: #82AAFF;">finishUpload</span><span style="color: #89DDFF;">($</span><span style="color: #A6ACCD;">name</span><span style="color: #89DDFF;">,</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">tmpPath</span><span style="color: #89DDFF;">,</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">isMultiple</span><span style="color: #89DDFF;">)</span><span style="color: #A6ACCD;"> </span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">16</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">{</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">17</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">$this-&gt;</span><span style="color: #82AAFF;">cleanupOldUploads</span><span style="color: #89DDFF;">();</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">18</span>&nbsp;</div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">19</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">files </span><span style="color: #89DDFF;">=</span><span style="color: #A6ACCD;"> </span><span style="color: #82AAFF;">collect</span><span style="color: #89DDFF;">($</span><span style="color: #A6ACCD;">tmpPath</span><span style="color: #89DDFF;">)-&gt;</span><span style="color: #82AAFF;">map</span><span style="color: #89DDFF;">(</span><span style="color: #C792EA;">function</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">($</span><span style="color: #A6ACCD;">i</span><span style="color: #89DDFF;">)</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">{</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">20</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">return</span><span style="color: #A6ACCD;"> </span><span style="color: #FFCB6B;">TemporaryUploadedFile</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">createFromLivewire</span><span style="color: #89DDFF;">($</span><span style="color: #A6ACCD;">i</span><span style="color: #89DDFF;">);</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">21</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">})-&gt;</span><span style="color: #82AAFF;">toArray</span><span style="color: #89DDFF;">();</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">22</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">$this-&gt;</span><span style="color: #82AAFF;">emitSelf</span><span style="color: #89DDFF;">(</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">upload:finished</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">,</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">name</span><span style="color: #89DDFF;">,</span><span style="color: #A6ACCD;"> </span><span style="color: #82AAFF;">collect</span><span style="color: #89DDFF;">($</span><span style="color: #A6ACCD;">files</span><span style="color: #89DDFF;">)-&gt;</span><span style="color: #A6ACCD;">map</span><span style="color: #89DDFF;">-&gt;</span><span style="color: #82AAFF;">getFilename</span><span style="color: #89DDFF;">()-&gt;</span><span style="color: #82AAFF;">toArray</span><span style="color: #89DDFF;">());</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">23</span>&nbsp;</div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">24</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">files </span><span style="color: #89DDFF;">=</span><span style="color: #A6ACCD;"> </span><span style="color: #82AAFF;">array_merge</span><span style="color: #89DDFF;">($this-&gt;</span><span style="color: #82AAFF;">getPropertyValue</span><span style="color: #89DDFF;">($</span><span style="color: #A6ACCD;">name</span><span style="color: #89DDFF;">),</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">files</span><span style="color: #89DDFF;">);</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">25</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">$this-&gt;</span><span style="color: #82AAFF;">syncInput</span><span style="color: #89DDFF;">($</span><span style="color: #A6ACCD;">name</span><span style="color: #89DDFF;">,</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">files</span><span style="color: #89DDFF;">);</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">26</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">}</span><span style="color: #A6ACCD;"> </span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">27</span>&nbsp;</div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">28</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #C792EA;">public</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">function</span><span style="color: #A6ACCD;"> </span><span style="color: #82AAFF;">render</span><span style="color: #89DDFF;">()</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">29</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">30</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">return</span><span style="color: #A6ACCD;"> </span><span style="color: #82AAFF;">view</span><span style="color: #89DDFF;">(</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">livewire.file-uploader</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">);</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">31</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">}</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">32</span><span style="color: #89DDFF;">}</span></div></code></pre>
<p>And that should be it! Now you can just keep adding files without them being removed. This &quot;fix&quot; is courtesy of this issue I found on <a href="https://github.com/livewire/livewire/issues/1230">Livewires github</a></p>
<h2>Removing uploaded files before submit</h2>
<p>As the files are only uploaded to a temp folder, you of course want to submit the form to finally save them. But perhaps the user added a file by accident and want to remove it without starting over. Let's add a remove button!</p>
<pre><code data-theme="material-theme-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 1</span><span style="color: #89DDFF;">@</span><span style="color: #89DDFF;">if</span><span style="color: #89DDFF;">(</span><span style="color: #82AAFF;">count</span><span style="color: #89DDFF;">($</span><span style="color: #A6ACCD;">files</span><span style="color: #89DDFF;">))</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 2</span><span style="color: #A6ACCD;">  </span><span style="color: #89DDFF;">&lt;</span><span style="color: #A6ACCD;">ul </span><span style="color: #C792EA;">class</span><span style="color: #89DDFF;">=</span><span style="color: #89DDFF;">&quot;</span><span style="color: #C3E88D;">mt-5 list-disc</span><span style="color: #89DDFF;">&quot;</span><span style="color: #89DDFF;">&gt;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 3</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">@</span><span style="color: #89DDFF;">foreach</span><span style="color: #89DDFF;">($</span><span style="color: #A6ACCD;">files </span><span style="color: #89DDFF;">as</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">file</span><span style="color: #89DDFF;">)</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 4</span><span style="color: #A6ACCD;">  </span><span style="color: #89DDFF;">&lt;</span><span style="color: #A6ACCD;">li</span><span style="color: #89DDFF;">&gt;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 5</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">{{$</span><span style="color: #A6ACCD;">file</span><span style="color: #89DDFF;">-&gt;</span><span style="color: #82AAFF;">getClientOriginalName</span><span style="color: #89DDFF;">()}}</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 6</span><span style="color: #A6ACCD;">  </span><span style="color: #89DDFF;">&lt;</span><span style="color: #A6ACCD;">button </span><span style="color: #C792EA;">class</span><span style="color: #89DDFF;">=</span><span style="color: #89DDFF;">&quot;</span><span style="color: #C3E88D;">text-red-500</span><span style="color: #89DDFF;">&quot;</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">@</span><span style="color: #A6ACCD;">click</span><span style="color: #89DDFF;">=</span><span style="color: #89DDFF;">&quot;</span><span style="color: #C3E88D;">removeUpload(&#39;{</span><span style="color: #89DDFF;">{$</span><span style="color: #A6ACCD;">file</span><span style="color: #89DDFF;">-&gt;</span><span style="color: #82AAFF;">getFilename</span><span style="color: #89DDFF;">()}</span><span style="color: #C3E88D;">}&#39;)</span><span style="color: #89DDFF;">&quot;</span><span style="color: #89DDFF;">&gt;</span><span style="color: #A6ACCD;">X</span><span style="color: #89DDFF;">&lt;/</span><span style="color: #A6ACCD;">button</span><span style="color: #89DDFF;">&gt;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 7</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">&lt;/</span><span style="color: #A6ACCD;">li</span><span style="color: #89DDFF;">&gt;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 8</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">@</span><span style="color: #89DDFF;">endforeach</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 9</span><span style="color: #A6ACCD;">  </span><span style="color: #89DDFF;">&lt;/</span><span style="color: #A6ACCD;">ul</span><span style="color: #89DDFF;">&gt;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">10</span><span style="color: #89DDFF;">@</span><span style="color: #89DDFF;">endif</span></div></code></pre>
<p>When the user clicks it, it will call a function in AlpineJs that does the removal</p>
<pre><code data-theme="material-theme-palenight" data-lang="js" class='torchlight has-focus-lines' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 1</span><span style="color: #89DDFF;">&lt;</span><span style="color: #F07178;">script</span><span style="color: #89DDFF;">&gt;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 2</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;function fileUpload() </span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 3</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return </span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 4</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">isDropping</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #FF9CAC;">false</span><span style="color: #89DDFF;">,</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 5</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">isUploading</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #FF9CAC;">false</span><span style="color: #89DDFF;">,</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 6</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">progress</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">0</span><span style="color: #89DDFF;">,</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 7</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">handleFileSelect</span><span style="color: #89DDFF;">(</span><span style="color: #A6ACCD;">event</span><span style="color: #89DDFF;">)</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 8</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">if</span><span style="color: #F07178;"> (</span><span style="color: #A6ACCD;">event</span><span style="color: #89DDFF;">.</span><span style="color: #A6ACCD;">target</span><span style="color: #89DDFF;">.</span><span style="color: #A6ACCD;">files</span><span style="color: #89DDFF;">.</span><span style="color: #A6ACCD;">length</span><span style="color: #F07178;">) </span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 9</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">this.</span><span style="color: #82AAFF;">uploadFiles</span><span style="color: #F07178;">(</span><span style="color: #A6ACCD;">event</span><span style="color: #89DDFF;">.</span><span style="color: #A6ACCD;">target</span><span style="color: #89DDFF;">.</span><span style="color: #A6ACCD;">files</span><span style="color: #F07178;">)</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">10</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">}</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">11</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">},</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">12</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">handleFileDrop</span><span style="color: #89DDFF;">(</span><span style="color: #A6ACCD;">event</span><span style="color: #89DDFF;">)</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">13</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">if</span><span style="color: #F07178;"> (</span><span style="color: #A6ACCD;">event</span><span style="color: #89DDFF;">.</span><span style="color: #A6ACCD;">dataTransfer</span><span style="color: #89DDFF;">.</span><span style="color: #A6ACCD;">files</span><span style="color: #89DDFF;">.</span><span style="color: #A6ACCD;">length</span><span style="color: #F07178;"> </span><span style="color: #89DDFF;">&gt;</span><span style="color: #F07178;"> </span><span style="color: #F78C6C;">0</span><span style="color: #F07178;">) </span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">14</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">this.</span><span style="color: #82AAFF;">uploadFiles</span><span style="color: #F07178;">(</span><span style="color: #A6ACCD;">event</span><span style="color: #89DDFF;">.</span><span style="color: #A6ACCD;">dataTransfer</span><span style="color: #89DDFF;">.</span><span style="color: #A6ACCD;">files</span><span style="color: #F07178;">)</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">15</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">}</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">16</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">},</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">17</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">uploadFiles</span><span style="color: #89DDFF;">(</span><span style="color: #A6ACCD;">files</span><span style="color: #89DDFF;">)</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">18</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #C792EA;">const</span><span style="color: #F07178;"> </span><span style="color: #A6ACCD;">$this</span><span style="color: #F07178;"> </span><span style="color: #89DDFF;">=</span><span style="color: #F07178;"> </span><span style="color: #89DDFF;">this;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">19</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">this.</span><span style="color: #A6ACCD;">isUploading</span><span style="color: #F07178;"> </span><span style="color: #89DDFF;">=</span><span style="color: #F07178;"> </span><span style="color: #FF9CAC;">true</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">20</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">@this.</span><span style="color: #82AAFF;">uploadMultiple</span><span style="color: #F07178;">(</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">files</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">,</span><span style="color: #F07178;"> </span><span style="color: #A6ACCD;">files</span><span style="color: #89DDFF;">,</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">21</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #C792EA;">function</span><span style="color: #F07178;"> </span><span style="color: #89DDFF;">(</span><span style="color: #A6ACCD;">success</span><span style="color: #89DDFF;">)</span><span style="color: #F07178;"> </span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">22</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #A6ACCD;">$this</span><span style="color: #89DDFF;">.</span><span style="color: #A6ACCD;">isUploading</span><span style="color: #F07178;"> </span><span style="color: #89DDFF;">=</span><span style="color: #F07178;"> </span><span style="color: #FF9CAC;">false</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">23</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #A6ACCD;">$this</span><span style="color: #89DDFF;">.</span><span style="color: #A6ACCD;">progress</span><span style="color: #F07178;"> </span><span style="color: #89DDFF;">=</span><span style="color: #F07178;"> </span><span style="color: #F78C6C;">0</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">24</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">},</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">25</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #C792EA;">function</span><span style="color: #89DDFF;">(</span><span style="color: #A6ACCD;">error</span><span style="color: #89DDFF;">)</span><span style="color: #F07178;"> </span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">26</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #A6ACCD;">console</span><span style="color: #89DDFF;">.</span><span style="color: #82AAFF;">log</span><span style="color: #F07178;">(</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">error</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">,</span><span style="color: #F07178;"> </span><span style="color: #A6ACCD;">error</span><span style="color: #F07178;">)</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">27</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">},</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">28</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #C792EA;">function</span><span style="color: #F07178;"> </span><span style="color: #89DDFF;">(</span><span style="color: #A6ACCD;">event</span><span style="color: #89DDFF;">)</span><span style="color: #F07178;"> </span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">29</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #A6ACCD;">$this</span><span style="color: #89DDFF;">.</span><span style="color: #A6ACCD;">progress</span><span style="color: #F07178;"> </span><span style="color: #89DDFF;">=</span><span style="color: #F07178;"> </span><span style="color: #A6ACCD;">event</span><span style="color: #89DDFF;">.</span><span style="color: #A6ACCD;">detail</span><span style="color: #89DDFF;">.</span><span style="color: #A6ACCD;">progress</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">30</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">}</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">31</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">32</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">},</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">33</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">removeUpload</span><span style="color: #89DDFF;">(</span><span style="color: #A6ACCD;">filename</span><span style="color: #89DDFF;">)</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">{</span><span style="color: #F07178;"> </span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">34</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">@this.</span><span style="color: #82AAFF;">removeUpload</span><span style="color: #F07178;">(</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">files</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">,</span><span style="color: #F07178;"> </span><span style="color: #A6ACCD;">filename</span><span style="color: #F07178;">)</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">35</span><span style="color: #F07178;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">},</span><span style="color: #A6ACCD;"> </span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">36</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">}</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">37</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">}</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">38</span><span style="color: #89DDFF;">&lt;/</span><span style="color: #F07178;">script</span><span style="color: #89DDFF;">&gt;</span></div></code></pre>
<p>This again just uses a built-in livewire method to remove the file. Now you just need to add validation and the form submission yourself.</p>
<h2>The end</h2>
<p>I hope that this guide helped you build something great. Feel free to reach out if you feel this guide is missing something or has any mistakes. <a href="https://twitter.com/rsinnbeck">@rsinnbeck</a></p>
]]>
            </summary>
                                    <updated>2022-09-05T14:00:20+00:00</updated>
        </entry>
            <entry>
            <title><![CDATA[Adding bound toSql() to laravel]]></title>
            <link rel="alternate" href="https://sinnbeck.dev/posts/adding-bound-tosql-to-laravel" />
            <id>https://sinnbeck.dev/5</id>
            <author>
                <name><![CDATA[René Sinnbeck]]></name>
                <email><![CDATA[-]]></email>

            </author>
            <summary type="html">
                <![CDATA[<h1>Adding bound toSql() to laravel</h1><p>Often when debugging I find myself using <code>-&gt;toSql()</code> to get the SQL query string used by the query builder,
to see if it looks correct. Sadly this does not work when the query includes parameters as these are only used for
binding in PDO.</p>
<p>It would be nice to be able to get the query with the parameters as well, so let's add that to laravel!</p>
<h2>But how?!</h2>
<p>Luckily laravel supports macros, which lets us easily extend various built in classes in laravel,
without having to edit the vendor source files (Which can be overwritten every time we run composer update).</p>
<p>You can add a macro inside a service providers boot method. It works by calling the static <code>macro()</code> method
on the class we wish to extend. The first parameter is the new method name, and the second parameter is
a callback method that we call as if it was a native method on the underlying class.
Since it is being run from the class, we have access to <code>$this</code> inside the callback!</p>
<h2>Add a service provider</h2>
<p>First add a service provider that can hold the new macros.</p>
<pre><code data-theme="material-theme-palenight" data-lang="bash" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #FFCB6B;">php</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">artisan</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">make:provider</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">MacroServiceProvider</span></div></code></pre>
<p>This will give you a clean service provider like this</p>
<pre><code data-theme="material-theme-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 1</span><span style="color: #89DDFF;">&lt;?php</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 2</span>&nbsp;</div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 3</span><span style="color: #F78C6C;">namespace</span><span style="color: #A6ACCD;"> </span><span style="color: #FFCB6B;">App</span><span style="color: #89DDFF;">\</span><span style="color: #FFCB6B;">Providers</span><span style="color: #89DDFF;">;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 4</span>&nbsp;</div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 5</span><span style="color: #F78C6C;">use</span><span style="color: #FFCB6B;"> </span><span style="color: #A6ACCD;">Illuminate</span><span style="color: #89DDFF;">\</span><span style="color: #A6ACCD;">Support</span><span style="color: #89DDFF;">\</span><span style="color: #A6ACCD;">ServiceProvider</span><span style="color: #89DDFF;">;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 6</span>&nbsp;</div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 7</span><span style="color: #C792EA;">class</span><span style="color: #A6ACCD;"> </span><span style="color: #FFCB6B;">MacroServiceProvider</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">extends</span><span style="color: #A6ACCD;"> </span><span style="color: #FFCB6B;">ServiceProvider</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 8</span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 9</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #676E95;">/**</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">10</span><span style="color: #676E95;">&nbsp;&nbsp;&nbsp;&nbsp; * Register services.</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">11</span><span style="color: #676E95;">&nbsp;&nbsp;&nbsp;&nbsp; *</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">12</span><span style="color: #676E95;">&nbsp;&nbsp;&nbsp;&nbsp; * </span><span style="color: #F78C6C;">@return</span><span style="color: #676E95;"> </span><span style="color: #F78C6C;">void</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">13</span><span style="color: #676E95;">&nbsp;&nbsp;&nbsp;&nbsp; */</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">14</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #C792EA;">public</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">function</span><span style="color: #A6ACCD;"> </span><span style="color: #82AAFF;">register</span><span style="color: #89DDFF;">()</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">15</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">16</span><span style="color: #89DDFF;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #676E95;">//</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">17</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">}</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">18</span>&nbsp;</div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">19</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #676E95;">/**</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">20</span><span style="color: #676E95;">&nbsp;&nbsp;&nbsp;&nbsp; * Bootstrap services.</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">21</span><span style="color: #676E95;">&nbsp;&nbsp;&nbsp;&nbsp; *</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">22</span><span style="color: #676E95;">&nbsp;&nbsp;&nbsp;&nbsp; * </span><span style="color: #F78C6C;">@return</span><span style="color: #676E95;"> </span><span style="color: #F78C6C;">void</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">23</span><span style="color: #676E95;">&nbsp;&nbsp;&nbsp;&nbsp; */</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">24</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #C792EA;">public</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">function</span><span style="color: #A6ACCD;"> </span><span style="color: #82AAFF;">boot</span><span style="color: #89DDFF;">()</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">25</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">26</span><span style="color: #89DDFF;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #676E95;">//</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">27</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">}</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">28</span><span style="color: #89DDFF;">}</span></div></code></pre>
<h2>Add the macro</h2>
<p>We delete the <code>register</code> method since we don't need it, and add the following code to the <code>boot</code> method</p>
<pre><code data-theme="material-theme-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 1</span><span style="color: #FFCB6B;">Builder</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">macro</span><span style="color: #89DDFF;">(</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">toBoundSql</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">,</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">function</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">()</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 2</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #676E95;">/* @var Builder $this */</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 3</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">bindings </span><span style="color: #89DDFF;">=</span><span style="color: #A6ACCD;"> </span><span style="color: #82AAFF;">array_map</span><span style="color: #89DDFF;">(</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 4</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #C792EA;">fn</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">($</span><span style="color: #A6ACCD;">parameter</span><span style="color: #89DDFF;">)</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">=&gt;</span><span style="color: #A6ACCD;"> </span><span style="color: #82AAFF;">is_string</span><span style="color: #89DDFF;">($</span><span style="color: #A6ACCD;">parameter</span><span style="color: #89DDFF;">)</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">?</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">&quot;</span><span style="color: #C3E88D;">&#39;</span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">parameter</span><span style="color: #C3E88D;">&#39;</span><span style="color: #89DDFF;">&quot;</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">parameter</span><span style="color: #89DDFF;">,</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 5</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">$this-&gt;</span><span style="color: #82AAFF;">getBindings</span><span style="color: #89DDFF;">()</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 6</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">);</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 7</span>&nbsp;</div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 8</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">return</span><span style="color: #A6ACCD;"> </span><span style="color: #FFCB6B;">Str</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">replaceArray</span><span style="color: #89DDFF;">(</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 9</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">?</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">,</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">10</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">bindings</span><span style="color: #89DDFF;">,</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">11</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">$this-&gt;</span><span style="color: #82AAFF;">toSql</span><span style="color: #89DDFF;">()</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">12</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">);</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">13</span><span style="color: #89DDFF;">});</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">14</span>&nbsp;</div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">15</span><span style="color: #FFCB6B;">EloquentBuilder</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">macro</span><span style="color: #89DDFF;">(</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">toBoundSql</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">,</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">function</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">()</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">16</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">return</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">$this-&gt;</span><span style="color: #82AAFF;">toBase</span><span style="color: #89DDFF;">()-&gt;</span><span style="color: #82AAFF;">toBoundSql</span><span style="color: #89DDFF;">();</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">17</span><span style="color: #89DDFF;">});</span></div></code></pre>
<p>The end result should look like this.</p>
<pre><code data-theme="material-theme-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 1</span><span style="color: #89DDFF;">&lt;?php</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 2</span>&nbsp;</div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 3</span><span style="color: #F78C6C;">namespace</span><span style="color: #A6ACCD;"> </span><span style="color: #FFCB6B;">App</span><span style="color: #89DDFF;">\</span><span style="color: #FFCB6B;">Providers</span><span style="color: #89DDFF;">;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 4</span>&nbsp;</div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 5</span><span style="color: #F78C6C;">use</span><span style="color: #FFCB6B;"> </span><span style="color: #A6ACCD;">Illuminate</span><span style="color: #89DDFF;">\</span><span style="color: #A6ACCD;">Support</span><span style="color: #89DDFF;">\</span><span style="color: #A6ACCD;">Str</span><span style="color: #89DDFF;">;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 6</span><span style="color: #F78C6C;">use</span><span style="color: #FFCB6B;"> </span><span style="color: #A6ACCD;">Illuminate</span><span style="color: #89DDFF;">\</span><span style="color: #A6ACCD;">Database</span><span style="color: #89DDFF;">\</span><span style="color: #A6ACCD;">Query</span><span style="color: #89DDFF;">\</span><span style="color: #A6ACCD;">Builder</span><span style="color: #89DDFF;">;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 7</span><span style="color: #F78C6C;">use</span><span style="color: #FFCB6B;"> </span><span style="color: #A6ACCD;">Illuminate</span><span style="color: #89DDFF;">\</span><span style="color: #A6ACCD;">Support</span><span style="color: #89DDFF;">\</span><span style="color: #A6ACCD;">ServiceProvider</span><span style="color: #89DDFF;">;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 8</span><span style="color: #F78C6C;">use</span><span style="color: #FFCB6B;"> </span><span style="color: #A6ACCD;">Illuminate</span><span style="color: #89DDFF;">\</span><span style="color: #A6ACCD;">Database</span><span style="color: #89DDFF;">\</span><span style="color: #A6ACCD;">Eloquent</span><span style="color: #89DDFF;">\</span><span style="color: #A6ACCD;">Builder</span><span style="color: #FFCB6B;"> </span><span style="color: #F78C6C;">as</span><span style="color: #FFCB6B;"> EloquentBuilder</span><span style="color: #89DDFF;">;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 9</span>&nbsp;</div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">10</span><span style="color: #C792EA;">class</span><span style="color: #A6ACCD;"> </span><span style="color: #FFCB6B;">MacroServiceProvider</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">extends</span><span style="color: #A6ACCD;"> </span><span style="color: #FFCB6B;">ServiceProvider</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">11</span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">12</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #676E95;">/**</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">13</span><span style="color: #676E95;">&nbsp;&nbsp;&nbsp;&nbsp; * Bootstrap services.</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">14</span><span style="color: #676E95;">&nbsp;&nbsp;&nbsp;&nbsp; *</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">15</span><span style="color: #676E95;">&nbsp;&nbsp;&nbsp;&nbsp; * </span><span style="color: #F78C6C;">@return</span><span style="color: #676E95;"> </span><span style="color: #F78C6C;">void</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">16</span><span style="color: #676E95;">&nbsp;&nbsp;&nbsp;&nbsp; */</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">17</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #C792EA;">public</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">function</span><span style="color: #A6ACCD;"> </span><span style="color: #82AAFF;">boot</span><span style="color: #89DDFF;">()</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">18</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">19</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FFCB6B;">Builder</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">macro</span><span style="color: #89DDFF;">(</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">toBoundSql</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">,</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">function</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">()</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">20</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #676E95;">/* @var Builder $this */</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">21</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">bindings </span><span style="color: #89DDFF;">=</span><span style="color: #A6ACCD;"> </span><span style="color: #82AAFF;">array_map</span><span style="color: #89DDFF;">(</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">22</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #C792EA;">fn</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">($</span><span style="color: #A6ACCD;">parameter</span><span style="color: #89DDFF;">)</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">=&gt;</span><span style="color: #A6ACCD;"> </span><span style="color: #82AAFF;">is_string</span><span style="color: #89DDFF;">($</span><span style="color: #A6ACCD;">parameter</span><span style="color: #89DDFF;">)</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">?</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">&quot;</span><span style="color: #C3E88D;">&#39;</span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">parameter</span><span style="color: #C3E88D;">&#39;</span><span style="color: #89DDFF;">&quot;</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">parameter</span><span style="color: #89DDFF;">,</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">23</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">$this-&gt;</span><span style="color: #82AAFF;">getBindings</span><span style="color: #89DDFF;">()</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">24</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">);</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">25</span>&nbsp;</div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">26</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">return</span><span style="color: #A6ACCD;"> </span><span style="color: #FFCB6B;">Str</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">replaceArray</span><span style="color: #89DDFF;">(</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">27</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">?</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">,</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">28</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">bindings</span><span style="color: #89DDFF;">,</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">29</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">$this-&gt;</span><span style="color: #82AAFF;">toSql</span><span style="color: #89DDFF;">()</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">30</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">);</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">31</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">});</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">32</span>&nbsp;</div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">33</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FFCB6B;">EloquentBuilder</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">macro</span><span style="color: #89DDFF;">(</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">toBoundSql</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">,</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">function</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">()</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">34</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">return</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">$this-&gt;</span><span style="color: #82AAFF;">toBase</span><span style="color: #89DDFF;">()-&gt;</span><span style="color: #82AAFF;">toBoundSql</span><span style="color: #89DDFF;">();</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">35</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">});</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">36</span>&nbsp;</div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">37</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">}</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">38</span><span style="color: #89DDFF;">}</span></div></code></pre>
<p>There are two macros with the same name.
The first is for binding the method to the DB query builder, that binding is what makes all of this work.
However, we are not quite there yet, this won't work with eloquent as it will just return the string to eloquent.
That means that we will output the eloquent builder class object, instead of a string.
To fix this, we add the second macro, which will bind directly to eloquent.
All it does is get the string by calling the underlying query builder, and return the result as a string.</p>
<h2>Let's try it out!</h2>
<p>To test it out, you can add the following</p>
<p>This is what it looks like without the new macros.</p>
<pre><code data-theme="material-theme-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">1</span><span style="color: #82AAFF;">dd</span><span style="color: #89DDFF;">(\</span><span style="color: #A6ACCD;">App</span><span style="color: #89DDFF;">\</span><span style="color: #A6ACCD;">Models</span><span style="color: #89DDFF;">\</span><span style="color: #FFCB6B;">User</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">where</span><span style="color: #89DDFF;">(</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">id</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">,</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">&gt;</span><span style="color: #89DDFF;">&#39;.</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">100</span><span style="color: #89DDFF;">)-&gt;</span><span style="color: #82AAFF;">latest</span><span style="color: #89DDFF;">()-&gt;</span><span style="color: #82AAFF;">toSql</span><span style="color: #89DDFF;">());</span></div></code></pre>
<p>It gives us this SQL.</p>
<pre><code data-theme="material-theme-palenight" data-lang="sql" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">1</span><span style="color: #F78C6C;">select</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">*</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">from</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">`</span><span style="color: #C3E88D;">users</span><span style="color: #89DDFF;">`</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">where</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">`</span><span style="color: #C3E88D;">id</span><span style="color: #89DDFF;">`</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">=</span><span style="color: #A6ACCD;"> ? </span><span style="color: #F78C6C;">and</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">`</span><span style="color: #C3E88D;">users</span><span style="color: #89DDFF;">`</span><span style="color: #A6ACCD;">.</span><span style="color: #89DDFF;">`</span><span style="color: #C3E88D;">deleted_at</span><span style="color: #89DDFF;">`</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">is</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">null</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">order by</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">`</span><span style="color: #C3E88D;">created_at</span><span style="color: #89DDFF;">`</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">desc</span></div></code></pre>
<p>After we added the new macros.</p>
<pre><code data-theme="material-theme-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">1</span><span style="color: #82AAFF;">dd</span><span style="color: #89DDFF;">(\</span><span style="color: #A6ACCD;">App</span><span style="color: #89DDFF;">\</span><span style="color: #A6ACCD;">Models</span><span style="color: #89DDFF;">\</span><span style="color: #FFCB6B;">User</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">where</span><span style="color: #89DDFF;">(</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">id</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">,</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">&gt;</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">,</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">100</span><span style="color: #89DDFF;">)-&gt;</span><span style="color: #82AAFF;">latest</span><span style="color: #89DDFF;">()-&gt;</span><span style="color: #82AAFF;">toBoundSql</span><span style="color: #89DDFF;">());</span></div></code></pre>
<p>This should give us</p>
<pre><code data-theme="material-theme-palenight" data-lang="sql" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">1</span><span style="color: #F78C6C;">select</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">*</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">from</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">`</span><span style="color: #C3E88D;">users</span><span style="color: #89DDFF;">`</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">where</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">`</span><span style="color: #C3E88D;">id</span><span style="color: #89DDFF;">`</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">&gt;</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">100</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">and</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">`</span><span style="color: #C3E88D;">users</span><span style="color: #89DDFF;">`</span><span style="color: #A6ACCD;">.</span><span style="color: #89DDFF;">`</span><span style="color: #C3E88D;">deleted_at</span><span style="color: #89DDFF;">`</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">is</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">null</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">order by</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">`</span><span style="color: #C3E88D;">created_at</span><span style="color: #89DDFF;">`</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">desc</span></div></code></pre>
<p>Or we can try the DB version</p>
<pre><code data-theme="material-theme-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">1</span><span style="color: #82AAFF;">dd</span><span style="color: #89DDFF;">(\</span><span style="color: #FFCB6B;">DB</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">table</span><span style="color: #89DDFF;">(</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">users</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">)-&gt;</span><span style="color: #82AAFF;">where</span><span style="color: #89DDFF;">(</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">id</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">,</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">&gt;</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">,</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">100</span><span style="color: #89DDFF;">)-&gt;</span><span style="color: #82AAFF;">latest</span><span style="color: #89DDFF;">()-&gt;</span><span style="color: #82AAFF;">toBoundSql</span><span style="color: #89DDFF;">());</span></div></code></pre>
<p>Which will give us</p>
<pre><code data-theme="material-theme-palenight" data-lang="sql" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">1</span><span style="color: #F78C6C;">select</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">*</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">from</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">`</span><span style="color: #C3E88D;">users</span><span style="color: #89DDFF;">`</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">where</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">`</span><span style="color: #C3E88D;">id</span><span style="color: #89DDFF;">`</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">&gt;</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">100</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">order by</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">`</span><span style="color: #C3E88D;">created_at</span><span style="color: #89DDFF;">`</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">desc</span></div></code></pre>
<h2>Conclusion</h2>
<p>As you can see adding new methods to laravel is quite easy, and getting a better SQL output only takes
a few lines of code. Even though packages like Debugbar or Clockwork handle this already,
I personally like being able to get the raw query inside of tinker or a command.</p>
]]>
            </summary>
                                    <updated>2022-02-28T14:00:20+00:00</updated>
        </entry>
            <entry>
            <title><![CDATA[Using lando to run laravel in docker]]></title>
            <link rel="alternate" href="https://sinnbeck.dev/posts/using-lando-to-run-laravel-in-docker" />
            <id>https://sinnbeck.dev/4</id>
            <author>
                <name><![CDATA[René Sinnbeck]]></name>
                <email><![CDATA[-]]></email>

            </author>
            <summary type="html">
                <![CDATA[<h1>Using lando to run laravel in docker</h1><p>Laravel comes with laravel sail, which is great! Personally I prefer using Lando as I find it gives me alot more features, like tooling, proxy and events.</p>
<p>I suggest looking through the <a href="https://docs.lando.dev/basics/basics.html#ok-cool-i-dig-it-what-do-i-need-to-get-started">docs</a> to see if lando is for you!</p>
<p>This tutorial assumes that you have already installed lando and docker by following the guide on the <a href="https://docs.lando.dev/basics/installation.html">website</a></p>
<p>You do not need php or composer installed locally to follow this guide!</p>
<h2>Set up a laravel project!</h2>
<p>First we will initialize a new laravel project.</p>
<blockquote>
<p>If you already have an existing project, just go into the root of the project and run <code>lando init</code> and follow the guide. After that you can skip to the next section!</p>
</blockquote>
<p>Go to the root of where you store your web projects. Now run  the following command. Be sure to replace <code>my-app</code> before you run it! <strong>The name cannot contain spaces!</strong></p>
<pre><code data-theme="material-theme-palenight" data-lang="bash" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #A6ACCD;">SITENAME</span><span style="color: #89DDFF;">=</span><span style="color: #A6ACCD;">my-app</span><span style="color: #89DDFF;">;</span><span style="color: #A6ACCD;"> </span><span style="color: #FFCB6B;">docker</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">run</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">--rm</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">--interactive</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">--tty</span><span style="color: #A6ACCD;"> \</span></div><div class='line'><span style="color: #A6ACCD;">  </span><span style="color: #FFCB6B;">--volume</span><span style="color: #A6ACCD;"> $PWD</span><span style="color: #FFCB6B;">:/app</span><span style="color: #A6ACCD;"> \</span></div><div class='line'><span style="color: #A6ACCD;">  </span><span style="color: #FFCB6B;">--user</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">$(</span><span style="color: #FFCB6B;">id</span><span style="color: #C3E88D;"> -u</span><span style="color: #89DDFF;">)</span><span style="color: #FFCB6B;">:</span><span style="color: #89DDFF;">$(</span><span style="color: #FFCB6B;">id</span><span style="color: #C3E88D;"> -g</span><span style="color: #89DDFF;">)</span><span style="color: #A6ACCD;"> \</span></div><div class='line'><span style="color: #A6ACCD;">  </span><span style="color: #FFCB6B;">composer</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">create-project</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">laravel/laravel</span><span style="color: #A6ACCD;"> $SITENAME </span><span style="color: #C3E88D;">^9.0</span><span style="color: #A6ACCD;"> \</span></div><div class='line'><span style="color: #A6ACCD;">  </span><span style="color: #89DDFF;">&amp;&amp;</span><span style="color: #A6ACCD;"> </span><span style="color: #82AAFF;">cd</span><span style="color: #A6ACCD;"> $SITENAME \</span></div><div class='line'><span style="color: #A6ACCD;">  </span><span style="color: #89DDFF;">&amp;&amp;</span><span style="color: #A6ACCD;"> </span><span style="color: #FFCB6B;">lando</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">init</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">--source</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">cwd</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">--webroot</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">./public</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">--recipe</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">laravel</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">--name</span><span style="color: #A6ACCD;"> $SITENAME</span></div></code></pre>
<blockquote>
<p>This is currently untested on Windows, so if it works/fails, feel free to send me a message on twitter at <a href="https://twitter.com/rsinnbeck">@rsinnbeck</a></p>
</blockquote>
<p>When the command has completed, you will now have a brand new laravel project with the name you provided.
In the root of the new directory you will find a file named <code>.lando.yml</code>. This is the config file generated by lando.</p>
<p>It will look something like this</p>
<pre><code data-theme="material-theme-palenight" data-lang="yml" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">1</span><span style="color: #A6ACCD;">name: my-app</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">2</span><span style="color: #A6ACCD;">recipe: laravel</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">3</span><span style="color: #A6ACCD;">config:</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">4</span><span style="color: #A6ACCD;">  webroot: ./public</span></div></code></pre>
<p>These lines mean the following:</p>
<ul>
<li>
<strong>name</strong>: The name lando uses to reference the site. This will also be prefix for the sitename when we open it in the browser later on!</li>
<li>
<strong>recipe</strong>: Lando uses recipes to make setting up a new project really fast. Here we are using the <a href="https://docs.lando.dev/config/laravel.html">laravel recipe</a>
config: Here we can pass config values to the recipe. We have set it to use the <code>./public</code> directory to serve files</li>
</ul>
<h2>Configure the docker containers</h2>
<p>Lets add some more items to our config so it resembles more what we normally use with laravel</p>
<pre><code data-theme="material-theme-palenight" data-lang="yaml" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">1</span><span style="color: #F07178;">name</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">my-app</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">2</span><span style="color: #F07178;">recipe</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">laravel</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">3</span><span style="color: #F07178;">config</span><span style="color: #89DDFF;">:</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">4</span><span style="color: #A6ACCD;">  </span><span style="color: #F07178;">webroot</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">./public</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">5</span><span style="color: #A6ACCD;">  </span><span style="color: #F07178;">php</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">8.0</span><span style="color: #89DDFF;">&#39;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">6</span><span style="color: #A6ACCD;">  </span><span style="color: #F07178;">via</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">apache</span><span style="color: #A6ACCD;"> </span><span style="color: #676E95;">#or nginx</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">7</span><span style="color: #A6ACCD;">  </span><span style="color: #F07178;">database</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">mysql</span><span style="color: #A6ACCD;"> </span><span style="color: #676E95;">#or mariadb or postgres</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">8</span><span style="color: #A6ACCD;">  </span><span style="color: #F07178;">cache</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">redis</span><span style="color: #A6ACCD;"> </span><span style="color: #676E95;">#or memcached</span></div></code></pre>
<p>Here we are setting which php version to use and we are telling lando which webserver, database and cache-server to install. All the containers can be suffixed with a version by using eg. <code>:2.0</code></p>
<p>Next set up your <code>.env</code> file with the correct values. If you are using postgres, the database config is a bit different. Refer to the <a href="https://docs.lando.dev/config/laravel.html#environment-file">docs</a> for the correct values.</p>
<pre><code data-theme="material-theme-palenight" data-lang="ini" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">1</span><span style="color: #F07178;">DB_CONNECTION</span><span style="color: #89DDFF;">=</span><span style="color: #A6ACCD;">mysql</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">2</span><span style="color: #F07178;">DB_HOST</span><span style="color: #89DDFF;">=</span><span style="color: #A6ACCD;">database</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">3</span><span style="color: #F07178;">DB_PORT</span><span style="color: #89DDFF;">=</span><span style="color: #A6ACCD;">3306</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">4</span><span style="color: #F07178;">DB_DATABASE</span><span style="color: #89DDFF;">=</span><span style="color: #A6ACCD;">laravel</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">5</span><span style="color: #F07178;">DB_USERNAME</span><span style="color: #89DDFF;">=</span><span style="color: #A6ACCD;">laravel</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">6</span><span style="color: #F07178;">DB_PASSWORD</span><span style="color: #89DDFF;">=</span><span style="color: #A6ACCD;">laravel</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">7</span>&nbsp;</div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">8</span><span style="color: #F07178;">REDIS_HOST</span><span style="color: #89DDFF;">=</span><span style="color: #A6ACCD;">cache</span></div></code></pre>
<h2>Time to try it out</h2>
<p>Now it's time to start our new app!
Simply run</p>
<pre><code data-theme="material-theme-palenight" data-lang="bash" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #FFCB6B;">lando</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">start</span></div></code></pre>
<p>Lando will now download the correct containers and start them all up. If all went well you should see a message looking something like this</p>
<pre><code data-theme="material-theme-palenight" data-lang="curl" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 1</span><span style="color: #A6ACCD;">Your app has started up correctly.</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 2</span><span style="color: #A6ACCD;">Here are some vitals:</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 3</span>&nbsp;</div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 4</span><span style="color: #A6ACCD;"> NAME&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my-app</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 5</span><span style="color: #A6ACCD;"> LOCATION&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/path/to/my-app</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 6</span><span style="color: #A6ACCD;"> SERVICES&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;appserver, database</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 7</span><span style="color: #A6ACCD;"> APPSERVER URLS  </span><span style="color: #89DDFF;">https://localhost:49548</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 8</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #89DDFF;">http://localhost:49549</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 9</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #89DDFF;">http://my-app.lndo.site/</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">10</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #89DDFF;">https://my-app.lndo.site/</span></div></code></pre>
<p>Your ports are probably different that above, but that is just because lando will find a random port on each run. Notice the services. These are the names of the containers we have built. The <code>appserver</code> is the main container used for running php!</p>
<p>You can now try opening one of the http:// links, and you should see the laravel welcome page!</p>
<h2>Using laravel through lando</h2>
<p>So the first thing we want to do is to make sure that all migrations are run. To run artisan commands we just replace <code>php</code> with lando, and it will run artisan inside the php container.</p>
<pre><code data-theme="material-theme-palenight" data-lang="bash" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #FFCB6B;">lando</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">artisan</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">migrate</span></div></code></pre>
<p>Try out a new more artisan command to see that it actually works just as running it locally!</p>
<p>Or you can use composer</p>
<pre><code data-theme="material-theme-palenight" data-lang="bash" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #FFCB6B;">lando</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">composer</span></div></code></pre>
<p>We can also run arbitrary php commands in the same way</p>
<pre><code data-theme="material-theme-palenight" data-lang="bash" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #FFCB6B;">lando</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">php</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">-v</span></div></code></pre>
<p>This should give you the php version number running inside the container</p>
<p>We can even jump right into the php container by running</p>
<pre><code data-theme="material-theme-palenight" data-lang="bash" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #FFCB6B;">lando</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">ssh</span></div></code></pre>
<p>You are now inside the container, and can run any command as if you were on your own computer. Type <code>exit</code> and his enter to get back to your own machine.</p>
<h2>Tooling</h2>
<p>Running migrations is something we need to do quite often, so let us make a handy shortcut for it!</p>
<p>Add the following to your <code>.lando.yml</code> file</p>
<pre><code data-theme="material-theme-palenight" data-lang="yaml" class='torchlight has-focus-lines' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 1</span><span style="color: #F07178;">name</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">my-app</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 2</span><span style="color: #F07178;">recipe</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">laravel</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 3</span><span style="color: #F07178;">config</span><span style="color: #89DDFF;">:</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 4</span><span style="color: #A6ACCD;">  </span><span style="color: #F07178;">webroot</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">./public</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 5</span><span style="color: #A6ACCD;">  </span><span style="color: #F07178;">php</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">8.0</span><span style="color: #89DDFF;">&#39;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 6</span><span style="color: #A6ACCD;">  </span><span style="color: #F07178;">via</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">apache</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 7</span><span style="color: #A6ACCD;">  </span><span style="color: #F07178;">database</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">mysql</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 8</span><span style="color: #A6ACCD;">  </span><span style="color: #F07178;">cache</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">redis</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 9</span><span style="color: #F07178;">tooling</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">10</span><span style="color: #A6ACCD;">  </span><span style="color: #F07178;">migrate</span><span style="color: #89DDFF;">:</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">11</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">service</span><span style="color: #89DDFF;">:</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">12</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">cmd</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">php artisan migrate</span><span style="color: #A6ACCD;"> </span></div></code></pre>
<p>We are adding a new command (tool) called migrate. It will be run on the service named <code>appserver</code> which is the one running php. The command it will run is <code>php artisan migrate</code></p>
<p>Now try running</p>
<pre><code data-theme="material-theme-palenight" data-lang="bash" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color: #FFCB6B;">lando</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">migrate</span></div></code></pre>
<p>As you can see it works, and we can now shorten the command just a bit. Feel free to add your own commands to make your life a little easier.</p>
<p>You can always get a full list of available commands by running <code>lando</code></p>
<h2>Add a container for running laravel mix</h2>
<p>In case you want to run laravel mix (or similar) we need a container for that.
Add the following to your <code>.lando.yml</code> file</p>
<pre><code data-theme="material-theme-palenight" data-lang="yaml" class='torchlight has-focus-lines' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 1</span><span style="color: #F07178;">name</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">my-app</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 2</span><span style="color: #F07178;">recipe</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">laravel</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 3</span><span style="color: #F07178;">config</span><span style="color: #89DDFF;">:</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 4</span><span style="color: #A6ACCD;">  </span><span style="color: #F07178;">webroot</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">./public</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 5</span><span style="color: #A6ACCD;">  </span><span style="color: #F07178;">php</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">8.0</span><span style="color: #89DDFF;">&#39;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 6</span><span style="color: #A6ACCD;">  </span><span style="color: #F07178;">via</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">apache</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 7</span><span style="color: #A6ACCD;">  </span><span style="color: #F07178;">database</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">mysql</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 8</span><span style="color: #A6ACCD;">  </span><span style="color: #F07178;">cache</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">redis</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 9</span><span style="color: #F07178;">services</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">10</span><span style="color: #A6ACCD;">  </span><span style="color: #F07178;">node</span><span style="color: #89DDFF;">:</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">11</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">type</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">node:16</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">12</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">scanner</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #FF9CAC;">false</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">13</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">build</span><span style="color: #89DDFF;">:</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">14</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;  </span><span style="color: #89DDFF;">-</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">npm install</span><span style="color: #A6ACCD;"> </span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">15</span><span style="color: #F07178;">tooling</span><span style="color: #89DDFF;">:</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">16</span><span style="color: #A6ACCD;">  </span><span style="color: #F07178;">migrate</span><span style="color: #89DDFF;">:</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">17</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">service</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">appserver</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">18</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">cmd</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">php artisan migrate</span></div></code></pre>
<p>Here we are telling lando to add an extra service, named <code>node</code>.</p>
<p>We want it to install <code>node</code> version <code>16</code>. Lando will automatically try scanning the new service to see if it can connect to it using http. As we do not want this, we will disable the scanner.</p>
<p>Lastly we will tell it to run <code>npm install</code> as soon as it is has added the new service (just so we don't forget)</p>
<p>Run <code>lando rebuild -y</code> to rebuild all the services, and add the new node service. As all the previous containers already exist and haven't changed, it should be pretty fast.</p>
<p>Like we did with the migrate command earlier we will now also add a command for running npm
Add the following to your <code>.lando.yml</code> file under the tooling: section</p>
<pre><code data-theme="material-theme-palenight" data-lang="yaml" class='torchlight has-focus-lines' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 1</span><span style="color: #F07178;">name</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">my-app</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 2</span><span style="color: #F07178;">recipe</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">laravel</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 3</span><span style="color: #F07178;">config</span><span style="color: #89DDFF;">:</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 4</span><span style="color: #A6ACCD;">  </span><span style="color: #F07178;">webroot</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">./public</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 5</span><span style="color: #A6ACCD;">  </span><span style="color: #F07178;">php</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">8.0</span><span style="color: #89DDFF;">&#39;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 6</span><span style="color: #A6ACCD;">  </span><span style="color: #F07178;">via</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">apache</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 7</span><span style="color: #A6ACCD;">  </span><span style="color: #F07178;">database</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">mysql</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 8</span><span style="color: #A6ACCD;">  </span><span style="color: #F07178;">cache</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">redis</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 9</span><span style="color: #F07178;">services</span><span style="color: #89DDFF;">:</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">10</span><span style="color: #A6ACCD;">  </span><span style="color: #F07178;">node</span><span style="color: #89DDFF;">:</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">11</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">type</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">node:16</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">12</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">scanner</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #FF9CAC;">false</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">13</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">build</span><span style="color: #89DDFF;">:</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">14</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;  </span><span style="color: #89DDFF;">-</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">npm install</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">15</span><span style="color: #F07178;">tooling</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">16</span><span style="color: #A6ACCD;">  </span><span style="color: #F07178;">migrate</span><span style="color: #89DDFF;">:</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">17</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">service</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">appserver</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">18</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">cmd</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">php artisan migrate</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">19</span><span style="color: #A6ACCD;">  </span><span style="color: #F07178;">npm</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">20</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">service</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">node</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">21</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">cmd</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">npm</span><span style="color: #A6ACCD;"> </span></div></code></pre>
<p>Now run <code>lando npm run dev</code> to confirm that it's working</p>
<h2>Add mailhog to catch mails</h2>
<p>Let us also add mailhog, to make sure we don't accidentially send emails to our clients</p>
<p>First add the service</p>
<pre><code data-theme="material-theme-palenight" data-lang="yaml" class='torchlight has-focus-lines' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 1</span><span style="color: #F07178;">name</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">my-app</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 2</span><span style="color: #F07178;">recipe</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">laravel</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 3</span><span style="color: #F07178;">config</span><span style="color: #89DDFF;">:</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 4</span><span style="color: #A6ACCD;">  </span><span style="color: #F07178;">webroot</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">./public</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 5</span><span style="color: #A6ACCD;">  </span><span style="color: #F07178;">php</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">8.0</span><span style="color: #89DDFF;">&#39;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 6</span><span style="color: #A6ACCD;">  </span><span style="color: #F07178;">via</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">apache</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 7</span><span style="color: #A6ACCD;">  </span><span style="color: #F07178;">database</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">mysql</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 8</span><span style="color: #A6ACCD;">  </span><span style="color: #F07178;">cache</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">redis</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 9</span><span style="color: #F07178;">services</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">10</span><span style="color: #A6ACCD;">  </span><span style="color: #F07178;">node</span><span style="color: #89DDFF;">:</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">11</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">type</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">node:16</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">12</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">scanner</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #FF9CAC;">false</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">13</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">build</span><span style="color: #89DDFF;">:</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">14</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;  </span><span style="color: #89DDFF;">-</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">npm install</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">15</span><span style="color: #A6ACCD;">  </span><span style="color: #F07178;">mail</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">16</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">type</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">mailhog</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">17</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">portforward</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #FF9CAC;">true</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">18</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">hogfrom</span><span style="color: #89DDFF;">:</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">19</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;  </span><span style="color: #89DDFF;">-</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">appserver</span><span style="color: #A6ACCD;"> </span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">20</span><span style="color: #F07178;">tooling</span><span style="color: #89DDFF;">:</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">21</span><span style="color: #A6ACCD;">  </span><span style="color: #F07178;">migrate</span><span style="color: #89DDFF;">:</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">22</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">service</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">appserver</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">23</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">cmd</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">php artisan migrate</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">24</span><span style="color: #A6ACCD;">  </span><span style="color: #F07178;">npm</span><span style="color: #89DDFF;">:</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">25</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">service</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">node</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">26</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">cmd</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">npm</span></div></code></pre>
<p>Here we add the <code>mailhog</code> service with the name <code>mail</code>.
We want to let the scanner check this service as it actually has a webinterface, and we tell lando to make sure that all http requests are directed to the container. We also tell mailhog that it should grab mails from the <code>appserver</code> container.</p>
<p>Run  <code>lando rebuild -y</code> to start the service.</p>
<p>Once the service is started, lando will show you an url on which you can see the mailhog interface. Here all emails from laravel will end up.</p>
<p>To make sure it works, change your <code>.env</code> file to use the new mail service</p>
<pre><code data-theme="material-theme-palenight" data-lang="ini" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">1</span><span style="color: #F07178;">MAIL_DRIVER</span><span style="color: #89DDFF;">=</span><span style="color: #A6ACCD;">smtp</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">2</span><span style="color: #F07178;">MAIL_HOST</span><span style="color: #89DDFF;">=</span><span style="color: #A6ACCD;">mail</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">3</span><span style="color: #F07178;">MAIL_PORT</span><span style="color: #89DDFF;">=</span><span style="color: #A6ACCD;">1025</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">4</span><span style="color: #F07178;">MAIL_USERNAME</span><span style="color: #89DDFF;">=</span><span style="color: #A6ACCD;">null</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">5</span><span style="color: #F07178;">MAIL_PASSWORD</span><span style="color: #89DDFF;">=</span><span style="color: #A6ACCD;">null</span></div></code></pre>
<p>Now when we send emails from laravel, they will be caught by mailhog.</p>
<h2>Proxy</h2>
<p>Before we wrap things up lets just add a proxy to the mailhog service, to make using it a bit easier.</p>
<p>Add the following to the bottom of your <code>.lando.yml</code> file (replace <code>my-app</code> with your actual project name)</p>
<pre><code data-theme="material-theme-palenight" data-lang="yaml" class='torchlight has-focus-lines' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 1</span><span style="color: #F07178;">name</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">my-app</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 2</span><span style="color: #F07178;">recipe</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">laravel</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 3</span><span style="color: #F07178;">config</span><span style="color: #89DDFF;">:</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 4</span><span style="color: #A6ACCD;">  </span><span style="color: #F07178;">webroot</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">./public</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 5</span><span style="color: #A6ACCD;">  </span><span style="color: #F07178;">php</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">8.0</span><span style="color: #89DDFF;">&#39;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 6</span><span style="color: #A6ACCD;">  </span><span style="color: #F07178;">via</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">apache</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 7</span><span style="color: #A6ACCD;">  </span><span style="color: #F07178;">database</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">mysql</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 8</span><span style="color: #A6ACCD;">  </span><span style="color: #F07178;">cache</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">redis</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 9</span><span style="color: #F07178;">services</span><span style="color: #89DDFF;">:</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">10</span><span style="color: #A6ACCD;">  </span><span style="color: #F07178;">node</span><span style="color: #89DDFF;">:</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">11</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">type</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">node:16</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">12</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">scanner</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #FF9CAC;">false</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">13</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">build</span><span style="color: #89DDFF;">:</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">14</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;  </span><span style="color: #89DDFF;">-</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">npm install</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">15</span><span style="color: #A6ACCD;">  </span><span style="color: #F07178;">mail</span><span style="color: #89DDFF;">:</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">16</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">type</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">mailhog</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">17</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">portforward</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #FF9CAC;">true</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">18</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">hogfrom</span><span style="color: #89DDFF;">:</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">19</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;  </span><span style="color: #89DDFF;">-</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">appserver</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">20</span><span style="color: #F07178;">tooling</span><span style="color: #89DDFF;">:</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">21</span><span style="color: #A6ACCD;">  </span><span style="color: #F07178;">migrate</span><span style="color: #89DDFF;">:</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">22</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">service</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">appserver</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">23</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">cmd</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">php artisan migrate</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">24</span><span style="color: #A6ACCD;">  </span><span style="color: #F07178;">npm</span><span style="color: #89DDFF;">:</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">25</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">service</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">node</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">26</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #F07178;">cmd</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">npm</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">27</span><span style="color: #F07178;">proxy</span><span style="color: #89DDFF;">:</span><span style="color: #A6ACCD;"> </span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">28</span><span style="color: #A6ACCD;">  </span><span style="color: #F07178;">mail</span><span style="color: #89DDFF;">:</span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">29</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">-</span><span style="color: #A6ACCD;"> </span><span style="color: #C3E88D;">mail.my-app.lndo.site</span><span style="color: #A6ACCD;"> </span></div></code></pre>
<p>Run <code>lando rebuild -y</code> and when it is done you will see that lando now have assigned the the mail service to the provided url. This makes opening it in the future alot easier, as we can bookmark the url.</p>
<h2>Wrap-up</h2>
<p>We have now successfully set up a new laravel app using lando. I hope it was easy to follow and that you will be using lando in the future.</p>
<p>If you want more lando tutorials, you can send me a message on Twitter at <a href="https://twitter.com/rsinnbeck">@rsinnbeck</a></p>
]]>
            </summary>
                                    <updated>2022-02-18T14:00:20+00:00</updated>
        </entry>
            <entry>
            <title><![CDATA[Laravel groupBy() error]]></title>
            <link rel="alternate" href="https://sinnbeck.dev/posts/laravel-groupby-error" />
            <id>https://sinnbeck.dev/3</id>
            <author>
                <name><![CDATA[René Sinnbeck]]></name>
                <email><![CDATA[-]]></email>

            </author>
            <summary type="html">
                <![CDATA[<h1>Laravel groupBy() error</h1><p>Helping out at the laracasts forum, I often see people running into issues with using <code>groupBy()</code> in queries. If you are running into errors like this</p>
<pre><code data-theme="material-theme-palenight" data-lang="sql" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">1</span><span style="color: #A6ACCD;">SQLSTATE[42000]:  Syntax error </span><span style="color: #F78C6C;">or</span><span style="color: #A6ACCD;"> access violation:</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">2</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">1055</span><span style="color: #A6ACCD;"> Expression  #</span><span style="color: #F78C6C;">1</span><span style="color: #A6ACCD;"> of </span><span style="color: #F78C6C;">SELECT</span><span style="color: #A6ACCD;"> list </span><span style="color: #F78C6C;">is</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">not</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">in</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">GROUP BY</span><span style="color: #A6ACCD;"> clause </span><span style="color: #F78C6C;">and</span><span style="color: #A6ACCD;"> contains nonaggregated colum</span></div></code></pre>
<p>.. then you are most likely the target of this blog post. Be aware that this post isn't meant to teach mysql <code>GROUP BY</code>, but rather give you a simple understanding of why the query is failing.</p>
<p>The error often comes from a query like this</p>
<pre><code data-theme="material-theme-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">1</span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">posts </span><span style="color: #89DDFF;">=</span><span style="color: #A6ACCD;"> </span><span style="color: #FFCB6B;">Post</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">query</span><span style="color: #89DDFF;">()</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">2</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">-&gt;</span><span style="color: #82AAFF;">groupBy</span><span style="color: #89DDFF;">(</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">category_id</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">)</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">3</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">-&gt;</span><span style="color: #82AAFF;">get</span><span style="color: #89DDFF;">();</span></div></code></pre>
<p>Now the idea is most likely that you just want to group the posts into their respective categories with all columns. But that is now how it works on a database level.</p>
<p>To make it easier to understand, lets use a spreadsheet as an example instead</p>
<table>
<thead>
<tr>
<th>id</th>
<th>name</th>
<th>category_id</th>
<th>author_id</th>
<th>visits</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Post 1</td>
<td>1</td>
<td>4</td>
<td>32</td>
</tr>
<tr>
<td>2</td>
<td>Post 2</td>
<td>1</td>
<td>8</td>
<td>12</td>
</tr>
<tr>
<td>3</td>
<td>Post 3</td>
<td>2</td>
<td>12</td>
<td>201</td>
</tr>
<tr>
<td>4</td>
<td>Post 4</td>
<td>2</td>
<td>4</td>
<td>3</td>
</tr>
</tbody>
</table>
<p>The database will always return rows, so let us try and run the above query on the data set.
Open a spreadsheet a try to make two rows with all data. It is two rows as category_id can either be 1 or 2.
So which <code>id</code> should it pick? 1 or 2? and the name, slug or even owner?</p>
<table>
<thead>
<tr>
<th>id</th>
<th>name</th>
<th>category_id</th>
<th>author_id</th>
<th>visits</th>
</tr>
</thead>
<tbody>
<tr>
<td>1 or 2</td>
<td>Post 1 or Post 2</td>
<td>1</td>
<td>4 or 8</td>
<td>32 or 12</td>
</tr>
<tr>
<td>3 or 4</td>
<td>Post 3 or Post 4</td>
<td>2</td>
<td>12 or 4</td>
<td>201 or 3</td>
</tr>
</tbody>
</table>
<p>Are you starting to see the problem?</p>
<h2>&quot;So how can I fix it?&quot;</h2>
<p>The simplest way is to only get only the columns we are grouping by, in this case <code>category_id</code></p>
<pre><code data-theme="material-theme-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">1</span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">posts </span><span style="color: #89DDFF;">=</span><span style="color: #A6ACCD;"> </span><span style="color: #FFCB6B;">Post</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">query</span><span style="color: #89DDFF;">()</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">2</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">-&gt;</span><span style="color: #82AAFF;">select</span><span style="color: #89DDFF;">(</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">category_id</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">)</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">3</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">-&gt;</span><span style="color: #82AAFF;">groupBy</span><span style="color: #89DDFF;">(</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">category_id</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">)</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">4</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">-&gt;</span><span style="color: #82AAFF;">get</span><span style="color: #89DDFF;">();</span></div></code></pre>
<table>
<thead>
<tr>
<th>category_id</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
</tr>
<tr>
<td>2</td>
</tr>
</tbody>
</table>
<p>While this works, maybe it isn't actually what we want. So now we need to plan out exactly what we want for each column. Perhaps we want to know what category id has the most visits. Here we can use what is called an aggregate function.</p>
<pre><code data-theme="material-theme-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">1</span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">posts </span><span style="color: #89DDFF;">=</span><span style="color: #A6ACCD;"> </span><span style="color: #FFCB6B;">Post</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">query</span><span style="color: #89DDFF;">()</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">2</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">-&gt;</span><span style="color: #82AAFF;">select</span><span style="color: #89DDFF;">(</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">category_id</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">,</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">\</span><span style="color: #FFCB6B;">DB</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">raw</span><span style="color: #89DDFF;">(</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">MAX(visits) as max_visits</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">))</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">3</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">-&gt;</span><span style="color: #82AAFF;">groupBy</span><span style="color: #89DDFF;">(</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">category_id</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">)</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">4</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">-&gt;</span><span style="color: #82AAFF;">get</span><span style="color: #89DDFF;">();</span></div></code></pre>
<p>We are using a raw query as there isn't anyway to specify the MAX function in a select in laravel. Also we are aliasing it to <code>max_visits</code> to make it easy to reference in laravel.</p>
<table>
<thead>
<tr>
<th>category_id</th>
<th>max_visits</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>32</td>
</tr>
<tr>
<td>2</td>
<td>201</td>
</tr>
</tbody>
</table>
<h2>&quot;But the query works in my database manager!&quot;</h2>
<p>You might indeed experience that the raw group by query actually works in your database manager. This is because laravel runs SQL queries in &quot;strict mode&quot;, while your database manager does not. It is possible to simply disable &quot;strict mode&quot; in laravel, by setting it to <code>false</code> in the database.php config file. While possible I cannot recommend doing so. It is better to spend the time learning how to write proper SQL queries, as the results given by turning &quot;strict mode&quot; off, can be unpredictable and lead to problems down the road.</p>
<h2>&quot;But I want all columns!&quot;</h2>
<p>Okay so you want to get all columns. Then the trick is to simply not use <code>groupBy()</code> on a database level. Instead you can use it with the returned collection instead. This will group the posts by the category it belongs to as expected (a nested collection)</p>
<pre><code data-theme="material-theme-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">1</span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">posts </span><span style="color: #89DDFF;">=</span><span style="color: #A6ACCD;"> </span><span style="color: #FFCB6B;">Post</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">query</span><span style="color: #89DDFF;">()</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">2</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">-&gt;</span><span style="color: #82AAFF;">get</span><span style="color: #89DDFF;">()</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">3</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">-&gt;</span><span style="color: #82AAFF;">groupBy</span><span style="color: #89DDFF;">(</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">category_id</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">);</span></div></code></pre>
<p>This is result in a structure like (here shown as a php array to make it easier to read)</p>
<pre><code data-theme="material-theme-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 1</span><span style="color: #89DDFF;">[</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 2</span>&nbsp;</div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 3</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">1</span><span style="color: #89DDFF;">&#39;</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">=&gt;</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">[</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 4</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">[</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">id</span><span style="color: #89DDFF;">&#39;</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">=&gt;</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">1</span><span style="color: #89DDFF;">,</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">name</span><span style="color: #89DDFF;">&#39;</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">=&gt;</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">Post 1</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">,</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">category_id</span><span style="color: #89DDFF;">&#39;</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">=&gt;</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">1</span><span style="color: #89DDFF;">,</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">author_id</span><span style="color: #89DDFF;">&#39;</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">=&gt;</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">4</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">visits</span><span style="color: #89DDFF;">&#39;</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">=&gt;</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">32</span><span style="color: #89DDFF;">],</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 5</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">[</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">id</span><span style="color: #89DDFF;">&#39;</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">=&gt;</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">2</span><span style="color: #89DDFF;">,</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">name</span><span style="color: #89DDFF;">&#39;</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">=&gt;</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">Post 2</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">,</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">category_id</span><span style="color: #89DDFF;">&#39;</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">=&gt;</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">1</span><span style="color: #89DDFF;">,</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">author_id</span><span style="color: #89DDFF;">&#39;</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">=&gt;</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">8</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">visits</span><span style="color: #89DDFF;">&#39;</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">=&gt;</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">12</span><span style="color: #89DDFF;">],</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 6</span><span style="color: #89DDFF;">],</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 7</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">2</span><span style="color: #89DDFF;">&#39;</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">=&gt;</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">[</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 8</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">[</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">id</span><span style="color: #89DDFF;">&#39;</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">=&gt;</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">3</span><span style="color: #89DDFF;">,</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">name</span><span style="color: #89DDFF;">&#39;</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">=&gt;</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">Post 3</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">,</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">category_id</span><span style="color: #89DDFF;">&#39;</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">=&gt;</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">2</span><span style="color: #89DDFF;">,</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">author_id</span><span style="color: #89DDFF;">&#39;</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">=&gt;</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">12</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">visits</span><span style="color: #89DDFF;">&#39;</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">=&gt;</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">201</span><span style="color: #89DDFF;">],</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 9</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">[</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">id</span><span style="color: #89DDFF;">&#39;</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">=&gt;</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">4</span><span style="color: #89DDFF;">,</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">name</span><span style="color: #89DDFF;">&#39;</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">=&gt;</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">Post 4</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">,</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">category_id</span><span style="color: #89DDFF;">&#39;</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">=&gt;</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">2</span><span style="color: #89DDFF;">,</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">author_id</span><span style="color: #89DDFF;">&#39;</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">=&gt;</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">4</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">visits</span><span style="color: #89DDFF;">&#39;</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">=&gt;</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">0</span><span style="color: #89DDFF;">],</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">10</span><span style="color: #89DDFF;">],</span></div></code></pre>
<h1>Wrap up</h1>
<p>So I hope this gave you some idea as to why your query is failing. If not, try asking at <a href="https://laracasts.com/discuss">https://laracasts.com/discuss</a></p>
]]>
            </summary>
                                    <updated>2022-02-17T14:00:20+00:00</updated>
        </entry>
            <entry>
            <title><![CDATA[Launch of a new blog]]></title>
            <link rel="alternate" href="https://sinnbeck.dev/posts/launch-of-a-new-blog" />
            <id>https://sinnbeck.dev/1</id>
            <author>
                <name><![CDATA[René Sinnbeck]]></name>
                <email><![CDATA[-]]></email>

            </author>
            <summary type="html">
                <![CDATA[<h1>Launch of a new blog</h1><p>I have for a long time considered making a blog, but just never got around to it.
So after my good friend <a href="https://tray2.se">Tray2</a> made his blog, I figured it was about time.</p>
<p>I hope to find some good topics over time. Most topics I write will be to help out people over at <a href="https://laracasts.com/discuss">https://laracasts.com/discuss</a>.
Often I see people struggle with the same issues over and over, so having some guides that people can just link to, might be helpful!</p>
]]>
            </summary>
                                    <updated>2021-12-16T14:00:20+00:00</updated>
        </entry>
            <entry>
            <title><![CDATA[Facades are singletons 🤯]]></title>
            <link rel="alternate" href="https://sinnbeck.dev/posts/facades-are-singletons" />
            <id>https://sinnbeck.dev/2</id>
            <author>
                <name><![CDATA[René Sinnbeck]]></name>
                <email><![CDATA[-]]></email>

            </author>
            <summary type="html">
                <![CDATA[<h1>Facades are singletons 🤯</h1><p>If you know a little about the service container, you also may know that you can explicitly bind things in the container as a singleton. What you might not know, is that they all actually are singletons.</p>
<p>Before we begin, let's quickly go through how the service container works.</p>
<p>NB: <em>All code examples uses PHP 8 syntax</em></p>
<h2>How the service container works</h2>
<p>In laravel you often inject classes in controllers like this</p>
<pre><code data-theme="material-theme-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">1</span><span style="color: #C792EA;">public</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">function</span><span style="color: #A6ACCD;"> </span><span style="color: #82AAFF;">show</span><span style="color: #89DDFF;">(</span><span style="color: #FFCB6B;">MyAwesomeClass</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">awesome</span><span style="color: #89DDFF;">):</span><span style="color: #A6ACCD;"> </span><span style="color: #FFCB6B;">View</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">2</span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">3</span><span style="color: #89DDFF;">}</span></div></code></pre>
<p>For this to work laravel needs to know how to resolve the class <code>MyAwesomeClass</code>. If the <code>MyAwesomeClass</code> constructor does not take any parameters or they are all resolvable using the container then laravel will just magically <code>new</code> up a class instance. For the sake of argument let's say that our class constructor requires a parameter to create a new instance of the class.</p>
<pre><code data-theme="material-theme-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 1</span><span style="color: #89DDFF;">&lt;?php</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 2</span><span style="color: #F78C6C;">namespace</span><span style="color: #A6ACCD;"> </span><span style="color: #FFCB6B;">App</span><span style="color: #89DDFF;">\</span><span style="color: #FFCB6B;">Foobar</span><span style="color: #89DDFF;">;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 3</span>&nbsp;</div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 4</span><span style="color: #C792EA;">class</span><span style="color: #A6ACCD;"> </span><span style="color: #FFCB6B;">MyAwesomeClass</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 5</span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 6</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #C792EA;">public</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">name</span><span style="color: #89DDFF;">;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 7</span>&nbsp;</div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 8</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #C792EA;">public</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">function</span><span style="color: #A6ACCD;"> </span><span style="color: #82AAFF;">__construct</span><span style="color: #89DDFF;">(</span><span style="color: #F78C6C;">string</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">name</span><span style="color: #89DDFF;">)</span><span style="color: #A6ACCD;">: void</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 9</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">10</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">$this-&gt;</span><span style="color: #A6ACCD;">name </span><span style="color: #89DDFF;">=</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">name</span><span style="color: #89DDFF;">;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">11</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">}</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">12</span>&nbsp;</div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">13</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #C792EA;">public</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">function</span><span style="color: #A6ACCD;"> </span><span style="color: #82AAFF;">setName</span><span style="color: #89DDFF;">(</span><span style="color: #F78C6C;">string</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">name</span><span style="color: #89DDFF;">):</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">self</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">14</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">15</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">$this-&gt;</span><span style="color: #A6ACCD;">name </span><span style="color: #89DDFF;">=</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">name</span><span style="color: #89DDFF;">;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">16</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">return</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">$this;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">17</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">}</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">18</span><span style="color: #89DDFF;">}</span></div></code></pre>
<p>We would then need to set this up in the container. This can be done as follows in a service provider.</p>
<pre><code data-theme="material-theme-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">1</span><span style="color: #89DDFF;">$this-&gt;</span><span style="color: #A6ACCD;">app</span><span style="color: #89DDFF;">-&gt;</span><span style="color: #82AAFF;">bind</span><span style="color: #89DDFF;">(</span><span style="color: #FFCB6B;">MyAwesomeClass</span><span style="color: #89DDFF;">::</span><span style="color: #F78C6C;">class</span><span style="color: #89DDFF;">,</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">function</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">($</span><span style="color: #A6ACCD;">app</span><span style="color: #89DDFF;">)</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">2</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">return</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">new</span><span style="color: #A6ACCD;"> </span><span style="color: #FFCB6B;">MyAwesomeClass</span><span style="color: #89DDFF;">(</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">foo</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">);</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">3</span><span style="color: #89DDFF;">});</span></div></code></pre>
<p>Here we tell the service container that it should new up an instance of the class with the parameter <code>$name = 'foo'</code> if it is requested from the container.</p>
<p>The service container will always make a new instance of the class each time we call it. This might not always be what we want. In some cases it might make more sense to always get the same exact instance. Examples of this can be the <code>Request</code> or <code>Session</code> class, as we want to be able to change these in one part of our app, and have the change reflected elsewhere (like changing the request in a middleware). We can easily change our binding from before so that it always returns the same <code>MyAwesomeClass</code> instance</p>
<pre><code data-theme="material-theme-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">1</span><span style="color: #89DDFF;">$this-&gt;</span><span style="color: #A6ACCD;">app</span><span style="color: #89DDFF;">-&gt;</span><span style="color: #82AAFF;">singleton</span><span style="color: #89DDFF;">(</span><span style="color: #FFCB6B;">MyAwesomeClass</span><span style="color: #89DDFF;">::</span><span style="color: #F78C6C;">class</span><span style="color: #89DDFF;">,</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">function</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">($</span><span style="color: #A6ACCD;">app</span><span style="color: #89DDFF;">)</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">2</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">return</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">new</span><span style="color: #A6ACCD;"> </span><span style="color: #FFCB6B;">MyAwesomeClass</span><span style="color: #89DDFF;">([</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">foo</span><span style="color: #89DDFF;">&#39;</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">=&gt;</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">bar</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">]);</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">3</span><span style="color: #89DDFF;">});</span></div></code></pre>
<p>A quick recap.
With the first example we will get a new class instance of the <code>MyAwesomeClass</code> each time.</p>
<pre><code data-theme="material-theme-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">1</span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">class1 </span><span style="color: #89DDFF;">=</span><span style="color: #A6ACCD;"> </span><span style="color: #82AAFF;">app</span><span style="color: #89DDFF;">(</span><span style="color: #FFCB6B;">MyAwesomeClass</span><span style="color: #89DDFF;">::</span><span style="color: #F78C6C;">class</span><span style="color: #89DDFF;">);</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">2</span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">class1</span><span style="color: #89DDFF;">-&gt;</span><span style="color: #82AAFF;">setName</span><span style="color: #89DDFF;">(</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">Foobar</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">);</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">3</span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">class2 </span><span style="color: #89DDFF;">=</span><span style="color: #A6ACCD;"> </span><span style="color: #82AAFF;">app</span><span style="color: #89DDFF;">(</span><span style="color: #FFCB6B;">MyAwesomeClass</span><span style="color: #89DDFF;">::</span><span style="color: #F78C6C;">class</span><span style="color: #89DDFF;">);</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">4</span>&nbsp;</div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">5</span><span style="color: #82AAFF;">echo</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">class1</span><span style="color: #89DDFF;">-&gt;</span><span style="color: #A6ACCD;">name</span><span style="color: #89DDFF;">;</span><span style="color: #A6ACCD;"> </span><span style="color: #676E95;">//shows Foobar</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">6</span><span style="color: #82AAFF;">echo</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">class2</span><span style="color: #89DDFF;">-&gt;</span><span style="color: #A6ACCD;">name</span><span style="color: #89DDFF;">;</span><span style="color: #A6ACCD;"> </span><span style="color: #676E95;">//shows foo</span></div></code></pre>
<p>And with the singleton we get the same class instance each time</p>
<pre><code data-theme="material-theme-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">1</span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">class1 </span><span style="color: #89DDFF;">=</span><span style="color: #A6ACCD;"> </span><span style="color: #82AAFF;">app</span><span style="color: #89DDFF;">(</span><span style="color: #FFCB6B;">MyAwesomeClass</span><span style="color: #89DDFF;">::</span><span style="color: #F78C6C;">class</span><span style="color: #89DDFF;">);</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">2</span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">class1</span><span style="color: #89DDFF;">-&gt;</span><span style="color: #82AAFF;">setName</span><span style="color: #89DDFF;">(</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">Foobar</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">)</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">3</span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">class2 </span><span style="color: #89DDFF;">=</span><span style="color: #A6ACCD;"> </span><span style="color: #82AAFF;">app</span><span style="color: #89DDFF;">(</span><span style="color: #FFCB6B;">MyAwesomeClass</span><span style="color: #89DDFF;">::</span><span style="color: #F78C6C;">class</span><span style="color: #89DDFF;">);</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">4</span>&nbsp;</div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">5</span><span style="color: #82AAFF;">echo</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">class1</span><span style="color: #89DDFF;">-&gt;</span><span style="color: #A6ACCD;">name</span><span style="color: #89DDFF;">;</span><span style="color: #A6ACCD;"> </span><span style="color: #676E95;">//shows Foobar</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">6</span><span style="color: #82AAFF;">echo</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">class2</span><span style="color: #89DDFF;">-&gt;</span><span style="color: #A6ACCD;">name</span><span style="color: #89DDFF;">;</span><span style="color: #A6ACCD;"> </span><span style="color: #676E95;">//shows Foobar</span></div></code></pre>
<h2>How facades work</h2>
<p>So now that you understand the basics of how the service container works, let's see how a Facade works.
A facade has just one method: <code>getFacadeAccessor()</code></p>
<pre><code data-theme="material-theme-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 1</span><span style="color: #89DDFF;">&lt;?php</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 2</span><span style="color: #F78C6C;">namespace</span><span style="color: #A6ACCD;"> </span><span style="color: #FFCB6B;">App</span><span style="color: #89DDFF;">\</span><span style="color: #FFCB6B;">Facades</span><span style="color: #89DDFF;">;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 3</span>&nbsp;</div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 4</span><span style="color: #F78C6C;">use</span><span style="color: #FFCB6B;"> </span><span style="color: #A6ACCD;">Illuminate</span><span style="color: #89DDFF;">\</span><span style="color: #A6ACCD;">Support</span><span style="color: #89DDFF;">\</span><span style="color: #A6ACCD;">Facades</span><span style="color: #89DDFF;">\</span><span style="color: #A6ACCD;">Facade</span><span style="color: #89DDFF;">;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 5</span>&nbsp;</div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 6</span><span style="color: #C792EA;">class</span><span style="color: #A6ACCD;"> </span><span style="color: #FFCB6B;">MyAwesomeClassFacade</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">extends</span><span style="color: #A6ACCD;"> </span><span style="color: #FFCB6B;">Facade</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 7</span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 8</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #676E95;">/**</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 9</span><span style="color: #676E95;">&nbsp;&nbsp;&nbsp;&nbsp; * Get the registered name of the component.</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">10</span><span style="color: #676E95;">&nbsp;&nbsp;&nbsp;&nbsp; *</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">11</span><span style="color: #676E95;">&nbsp;&nbsp;&nbsp;&nbsp; * </span><span style="color: #F78C6C;">@return</span><span style="color: #676E95;"> </span><span style="color: #F78C6C;">string</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">12</span><span style="color: #676E95;">&nbsp;&nbsp;&nbsp;&nbsp; */</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">13</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #C792EA;">protected</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">static</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">function</span><span style="color: #A6ACCD;"> </span><span style="color: #82AAFF;">getFacadeAccessor</span><span style="color: #89DDFF;">()</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">14</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">return</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">\</span><span style="color: #A6ACCD;">App</span><span style="color: #89DDFF;">\</span><span style="color: #A6ACCD;">Foobar</span><span style="color: #89DDFF;">\</span><span style="color: #FFCB6B;">MyAwesomeClass</span><span style="color: #89DDFF;">::</span><span style="color: #F78C6C;">class</span><span style="color: #89DDFF;">;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">15</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">}</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">16</span><span style="color: #89DDFF;">}</span></div></code></pre>
<p>Here we tell the facade that it is uses the <code>MyAwesomeClass</code> from before. That means that when we use the facade, it knows that it should return a <code>MyAwesomeClass</code> instance.</p>
<pre><code data-theme="material-theme-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">1</span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">myclass </span><span style="color: #89DDFF;">=</span><span style="color: #A6ACCD;"> </span><span style="color: #FFCB6B;">MyAwesomeClassFacade</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">setName</span><span style="color: #89DDFF;">(</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">foobar</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">);</span></div></code></pre>
<p>This will make a new instance of <code>MyAwesomeClass</code> and then automatically run the <code>setName()</code>method. This is done using the <code>__callStatic()</code>method in the base <code>Facade</code> class.</p>
<pre><code data-theme="material-theme-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 1</span><span style="color: #C792EA;">public</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">static</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">function</span><span style="color: #A6ACCD;"> </span><span style="color: #82AAFF;">__callStatic</span><span style="color: #89DDFF;">($</span><span style="color: #A6ACCD;">method</span><span style="color: #89DDFF;">,</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">args</span><span style="color: #89DDFF;">)</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 2</span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 3</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">instance </span><span style="color: #89DDFF;">=</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">static</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">getFacadeRoot</span><span style="color: #89DDFF;">();</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 4</span>&nbsp;</div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 5</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">if</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">(!</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">instance</span><span style="color: #89DDFF;">)</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 6</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">throw</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">new</span><span style="color: #A6ACCD;"> </span><span style="color: #FFCB6B;">RuntimeException</span><span style="color: #89DDFF;">(</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">A facade root has not been set.</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">);</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 7</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">}</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 8</span>&nbsp;</div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 9</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">return</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">instance</span><span style="color: #89DDFF;">-&gt;$</span><span style="color: #A6ACCD;">method</span><span style="color: #89DDFF;">(...$</span><span style="color: #A6ACCD;">args</span><span style="color: #89DDFF;">);</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">10</span><span style="color: #89DDFF;">}</span></div></code></pre>
<p>The <code>getFacadeRoot()</code> method calls the <code>resolveFacadeInstance()</code> method that is in charge of getting the correct class instance from the container.</p>
<h2>Why facades return the same class instance again and again (singleton)</h2>
<p>I hope you now have a basic understanding of how classes are resolved in laravel. No let's see why facades are indeed singletons.
As I said earlier, the <code>resolveFacadeInstance()</code> method is responsible for getting the correct class from the service container. Let's now have a look at what it does.</p>
<pre><code data-theme="material-theme-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 1</span><span style="color: #C792EA;">protected</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">static</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">function</span><span style="color: #A6ACCD;"> </span><span style="color: #82AAFF;">resolveFacadeInstance</span><span style="color: #89DDFF;">($</span><span style="color: #A6ACCD;">name</span><span style="color: #89DDFF;">)</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 2</span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 3</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">if</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">(</span><span style="color: #82AAFF;">is_object</span><span style="color: #89DDFF;">($</span><span style="color: #A6ACCD;">name</span><span style="color: #89DDFF;">))</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 4</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">return</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">name</span><span style="color: #89DDFF;">;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 5</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">}</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 6</span>&nbsp;</div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 7</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">if</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">(</span><span style="color: #82AAFF;">isset</span><span style="color: #89DDFF;">(</span><span style="color: #C792EA;">static</span><span style="color: #89DDFF;">::$</span><span style="color: #A6ACCD;">resolvedInstance</span><span style="color: #89DDFF;">[$</span><span style="color: #A6ACCD;">name</span><span style="color: #89DDFF;">]))</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 8</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">return</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">static</span><span style="color: #89DDFF;">::$</span><span style="color: #A6ACCD;">resolvedInstance</span><span style="color: #89DDFF;">[$</span><span style="color: #A6ACCD;">name</span><span style="color: #89DDFF;">];</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 9</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">}</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">10</span>&nbsp;</div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">11</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">if</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">(</span><span style="color: #C792EA;">static</span><span style="color: #89DDFF;">::$</span><span style="color: #A6ACCD;">app</span><span style="color: #89DDFF;">)</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">12</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">return</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">static</span><span style="color: #89DDFF;">::$</span><span style="color: #A6ACCD;">resolvedInstance</span><span style="color: #89DDFF;">[$</span><span style="color: #A6ACCD;">name</span><span style="color: #89DDFF;">]</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">=</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">static</span><span style="color: #89DDFF;">::$</span><span style="color: #A6ACCD;">app</span><span style="color: #89DDFF;">[$</span><span style="color: #A6ACCD;">name</span><span style="color: #89DDFF;">];</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">13</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">}</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">14</span><span style="color: #89DDFF;">}</span></div></code></pre>
<p>Let's break it down further, and we will start at the end.</p>
<pre><code data-theme="material-theme-palenight" data-lang="php" class='torchlight has-focus-lines' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 1</span><span style="color: #C792EA;">protected</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">static</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">function</span><span style="color: #A6ACCD;"> </span><span style="color: #82AAFF;">resolveFacadeInstance</span><span style="color: #89DDFF;">($</span><span style="color: #A6ACCD;">name</span><span style="color: #89DDFF;">)</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 2</span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 3</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">if</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">(</span><span style="color: #82AAFF;">is_object</span><span style="color: #89DDFF;">($</span><span style="color: #A6ACCD;">name</span><span style="color: #89DDFF;">))</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 4</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">return</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">name</span><span style="color: #89DDFF;">;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 5</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">}</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 6</span>&nbsp;</div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 7</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">if</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">(</span><span style="color: #82AAFF;">isset</span><span style="color: #89DDFF;">(</span><span style="color: #C792EA;">static</span><span style="color: #89DDFF;">::$</span><span style="color: #A6ACCD;">resolvedInstance</span><span style="color: #89DDFF;">[$</span><span style="color: #A6ACCD;">name</span><span style="color: #89DDFF;">]))</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 8</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">return</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">static</span><span style="color: #89DDFF;">::$</span><span style="color: #A6ACCD;">resolvedInstance</span><span style="color: #89DDFF;">[$</span><span style="color: #A6ACCD;">name</span><span style="color: #89DDFF;">];</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 9</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">}</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">10</span>&nbsp;</div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">11</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">if</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">(</span><span style="color: #C792EA;">static</span><span style="color: #89DDFF;">::$</span><span style="color: #A6ACCD;">app</span><span style="color: #89DDFF;">)</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">{</span><span style="color: #A6ACCD;"> </span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">12</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">return</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">static</span><span style="color: #89DDFF;">::$</span><span style="color: #A6ACCD;">resolvedInstance</span><span style="color: #89DDFF;">[$</span><span style="color: #A6ACCD;">name</span><span style="color: #89DDFF;">]</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">=</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">static</span><span style="color: #89DDFF;">::$</span><span style="color: #A6ACCD;">app</span><span style="color: #89DDFF;">[$</span><span style="color: #A6ACCD;">name</span><span style="color: #89DDFF;">];</span><span style="color: #A6ACCD;"> </span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">13</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">}</span><span style="color: #A6ACCD;"> </span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">14</span><span style="color: #89DDFF;">}</span></div></code></pre>
<p>The very last part of this code is what actually gets the instance back from the container. <code>static::$app[$name]</code>.</p>
<p><code>$app</code> is the container and the <code>$name</code> is the facade accessor from earlier. Now comes the <em>singleton</em> part when Laravel adds the returned value to a static array called <code>$resolvedInstance</code>, and if we look at the code before this, we will see that Laravel checks if the instance is already present in that array.</p>
<pre><code data-theme="material-theme-palenight" data-lang="php" class='torchlight has-focus-lines' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 1</span><span style="color: #C792EA;">protected</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">static</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">function</span><span style="color: #A6ACCD;"> </span><span style="color: #82AAFF;">resolveFacadeInstance</span><span style="color: #89DDFF;">($</span><span style="color: #A6ACCD;">name</span><span style="color: #89DDFF;">)</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 2</span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 3</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">if</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">(</span><span style="color: #82AAFF;">is_object</span><span style="color: #89DDFF;">($</span><span style="color: #A6ACCD;">name</span><span style="color: #89DDFF;">))</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 4</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">return</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">name</span><span style="color: #89DDFF;">;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 5</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">}</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 6</span>&nbsp;</div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 7</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">if</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">(</span><span style="color: #82AAFF;">isset</span><span style="color: #89DDFF;">(</span><span style="color: #C792EA;">static</span><span style="color: #89DDFF;">::$</span><span style="color: #A6ACCD;">resolvedInstance</span><span style="color: #89DDFF;">[$</span><span style="color: #A6ACCD;">name</span><span style="color: #89DDFF;">]))</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">{</span><span style="color: #A6ACCD;"> </span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 8</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">return</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">static</span><span style="color: #89DDFF;">::$</span><span style="color: #A6ACCD;">resolvedInstance</span><span style="color: #89DDFF;">[$</span><span style="color: #A6ACCD;">name</span><span style="color: #89DDFF;">];</span><span style="color: #A6ACCD;"> </span></div><div class='line line-focus'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 9</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">}</span><span style="color: #A6ACCD;"> </span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">10</span>&nbsp;</div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">11</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">if</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">(</span><span style="color: #C792EA;">static</span><span style="color: #89DDFF;">::$</span><span style="color: #A6ACCD;">app</span><span style="color: #89DDFF;">)</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">12</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">return</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">static</span><span style="color: #89DDFF;">::$</span><span style="color: #A6ACCD;">resolvedInstance</span><span style="color: #89DDFF;">[$</span><span style="color: #A6ACCD;">name</span><span style="color: #89DDFF;">]</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">=</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">static</span><span style="color: #89DDFF;">::$</span><span style="color: #A6ACCD;">app</span><span style="color: #89DDFF;">[$</span><span style="color: #A6ACCD;">name</span><span style="color: #89DDFF;">];</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">13</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">}</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">14</span><span style="color: #89DDFF;">}</span></div></code></pre>
<p>Since this array is static, it will remember it's content throughout the entire request. That means that if we have resolved a facade once, then the next time we resolve it we get the same instance! 🤯</p>
<h2>How to work around this!</h2>
<p>Laravel itself is actually quite good at working around this. Let's take the example of the Http client.
If we did this...</p>
<pre><code data-theme="material-theme-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">1</span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">response1 </span><span style="color: #89DDFF;">=</span><span style="color: #A6ACCD;"> </span><span style="color: #FFCB6B;">Http</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">withHeaders</span><span style="color: #89DDFF;">([</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">2</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">X-First</span><span style="color: #89DDFF;">&#39;</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">=&gt;</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">foo</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">,</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">3</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">X-Second</span><span style="color: #89DDFF;">&#39;</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">=&gt;</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">bar</span><span style="color: #89DDFF;">&#39;</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">4</span><span style="color: #89DDFF;">])-&gt;</span><span style="color: #82AAFF;">post</span><span style="color: #89DDFF;">(</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">http://example.com/users</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">,</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">[</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">5</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">name</span><span style="color: #89DDFF;">&#39;</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">=&gt;</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">Taylor</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">,</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">6</span><span style="color: #89DDFF;">]);</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">7</span>&nbsp;</div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">8</span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">response2 </span><span style="color: #89DDFF;">=</span><span style="color: #A6ACCD;"> </span><span style="color: #FFCB6B;">Http</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">get</span><span style="color: #89DDFF;">(</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">http://example2.com/users</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">);</span></div></code></pre>
<p>...it would be easy to assume that we would be using the same Http client instance, and yes, in fact we are! However laravel does a clever trick here with the methods.  These <code>withheaders()</code>, <code>post()</code>, <code>get()</code>, etc. don't actually exist on the underlying class. The class that the <code>Http</code> facade refers to is a <code>Factory</code> class which has the following method instead.</p>
<pre><code data-theme="material-theme-palenight" data-lang="php" class='torchlight has-highlight-lines' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 1</span><span style="color: #C792EA;">public</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">function</span><span style="color: #A6ACCD;"> </span><span style="color: #82AAFF;">__call</span><span style="color: #89DDFF;">($</span><span style="color: #A6ACCD;">method</span><span style="color: #89DDFF;">,</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">parameters</span><span style="color: #89DDFF;">)</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 2</span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 3</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">if</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">(</span><span style="color: #C792EA;">static</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">hasMacro</span><span style="color: #89DDFF;">($</span><span style="color: #A6ACCD;">method</span><span style="color: #89DDFF;">))</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 4</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">return</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">$this-&gt;</span><span style="color: #82AAFF;">macroCall</span><span style="color: #89DDFF;">($</span><span style="color: #A6ACCD;">method</span><span style="color: #89DDFF;">,</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">parameters</span><span style="color: #89DDFF;">);</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 5</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">}</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 6</span>&nbsp;</div><div class='line line-highlight line-has-background' style='background-color: #00000050'><span style="color:#676E95; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 7</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">return</span><span style="color: #A6ACCD;"> </span><span style="color: #82AAFF;">tap</span><span style="color: #89DDFF;">($this-&gt;</span><span style="color: #82AAFF;">newPendingRequest</span><span style="color: #89DDFF;">(),</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">function</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">($</span><span style="color: #A6ACCD;">request</span><span style="color: #89DDFF;">)</span><span style="color: #A6ACCD;"> </span><span style="color: #89DDFF;">{</span><span style="color: #A6ACCD;"> </span></div><div class='line line-highlight line-has-background' style='background-color: #00000050'><span style="color:#676E95; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 8</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">request</span><span style="color: #89DDFF;">-&gt;</span><span style="color: #82AAFF;">stub</span><span style="color: #89DDFF;">($this-&gt;</span><span style="color: #A6ACCD;">stubCallbacks</span><span style="color: #89DDFF;">);</span></div><div class='line line-highlight line-has-background' style='background-color: #00000050'><span style="color:#676E95; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number"> 9</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">})-&gt;{$</span><span style="color: #A6ACCD;">method</span><span style="color: #89DDFF;">}(...$</span><span style="color: #A6ACCD;">parameters</span><span style="color: #89DDFF;">);</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">10</span><span style="color: #89DDFF;">}</span></div></code></pre>
<p>So when you call a method that does not exist like <code>get()</code> it will first check if there is a macro with that name. If not it will create a new <code>PendingRequest</code> class instance, and return that.</p>
<pre><code data-theme="material-theme-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">1</span><span style="color: #C792EA;">protected</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">function</span><span style="color: #A6ACCD;"> </span><span style="color: #82AAFF;">newPendingRequest</span><span style="color: #89DDFF;">()</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">2</span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">3</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">return</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">new</span><span style="color: #A6ACCD;"> </span><span style="color: #FFCB6B;">PendingRequest</span><span style="color: #89DDFF;">($this);</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">4</span><span style="color: #89DDFF;">}</span></div></code></pre>
<h3>An easier fix</h3>
<p>If you need to ensure that you always get a new instance when using the facade, you can do this little trick (inspired by Spatie) on the class you are resolving by adding this.</p>
<pre><code data-theme="material-theme-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">1</span><span style="color: #C792EA;">public</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">function</span><span style="color: #A6ACCD;"> </span><span style="color: #82AAFF;">new</span><span style="color: #89DDFF;">()</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">2</span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">3</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">return</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">new</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">static</span><span style="color: #89DDFF;">();</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">4</span><span style="color: #89DDFF;">}</span></div></code></pre>
<p>You can then use the facade like this, to always get a new instance</p>
<pre><code data-theme="material-theme-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">1</span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">myclass </span><span style="color: #89DDFF;">=</span><span style="color: #A6ACCD;"> </span><span style="color: #FFCB6B;">MyAwesomeClassFacade</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">new</span><span style="color: #89DDFF;">();</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">2</span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">myclass</span><span style="color: #89DDFF;">-&gt;</span><span style="color: #82AAFF;">setName</span><span style="color: #89DDFF;">(</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">foobar</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">);</span></div></code></pre>
<p>This will call the <code>new()</code> method which will ensure that you get a new instance.</p>
<p><em><strong>Note:</strong></em>
Spatie has taken the facade completely out of the equation, and simply allow using the class itself as if it was a facade.</p>
<pre><code data-theme="material-theme-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">1</span><span style="color: #C792EA;">public</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">static</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">function</span><span style="color: #A6ACCD;"> </span><span style="color: #82AAFF;">new</span><span style="color: #89DDFF;">()</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">2</span><span style="color: #89DDFF;">{</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">3</span><span style="color: #A6ACCD;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #89DDFF;">return</span><span style="color: #A6ACCD;"> </span><span style="color: #F78C6C;">new</span><span style="color: #A6ACCD;"> </span><span style="color: #C792EA;">static</span><span style="color: #89DDFF;">();</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">4</span><span style="color: #89DDFF;">}</span></div></code></pre>
<p>Notice the static keyword. That means we can run it one the class directly.</p>
<pre><code data-theme="material-theme-palenight" data-lang="php" class='torchlight' style='background-color: #292D3E; --theme-selection-background: #00000080;'><!-- Syntax highlighted by torchlight.dev --><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">1</span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">myclass </span><span style="color: #89DDFF;">=</span><span style="color: #A6ACCD;"> </span><span style="color: #FFCB6B;">MyAwesomeClass</span><span style="color: #89DDFF;">::</span><span style="color: #82AAFF;">new</span><span style="color: #89DDFF;">();</span></div><div class='line'><span style="color:#3A3F58; text-align: right; -webkit-user-select: none; user-select: none;" class="line-number">2</span><span style="color: #89DDFF;">$</span><span style="color: #A6ACCD;">myclass</span><span style="color: #89DDFF;">-&gt;</span><span style="color: #82AAFF;">setName</span><span style="color: #89DDFF;">(</span><span style="color: #89DDFF;">&#39;</span><span style="color: #C3E88D;">foobar</span><span style="color: #89DDFF;">&#39;</span><span style="color: #89DDFF;">);</span></div></code></pre>
<h2>Wrapping up</h2>
<p>I hope this was helpful and that you learned something new.
This post was inspired by: <a href="https://github.com/laravel/ideas/issues/1088">Laravel GitHub issue #1088</a></p>
]]>
            </summary>
                                    <updated>2021-12-16T14:00:20+00:00</updated>
        </entry>
    </feed>
