Recently got a project that would have many tabs inside the page.
So when we click each tab, actually they really have a specific route that binds to each tab.
But the problems come when we change to another tab, and suddenly click refresh, it always redirects to old tabs.
Searching around the web, I found a discussion about this in livewire threads.
So in this post, I will show you how to do this by implementing some traits.
Maybe we can have a trait namely as UpdateUrlTrait.php
<?php
namespace App\Traits\Livewire;
trait UpdateUrlTrait
{
public $routeParams = [];
/**
* Change url with route name and params
*
* @param string|null $routeName
* @param array|null $params
* @return \Livewire\Event|null
*/
protected function changeUrl(?string $routeName = null, ?array $params = [])
{
return $routeName
? $this->emit('urlChanged', route($routeName, $params))
: null;
}
/**
* Change room tab url with route name and params
*
* @param string|null $routeName
* @param string|null $tab
* @return \Livewire\Event|null
*/
public function onChangeRoomTab(?string $routeName = null, ?string $tab = null)
{
$this->routeParams['room'] ??= $this->roomId;
$this->routeParams['tab'] = $tab;
return $routeName && $this->routeParams['room']
? $this->changeUrl($routeName, $this->routeParams)
: null;
}
}
Then, I’ll create another js file which will be stored inside resources/js, since it’s better way to keep your js file in bundler. I name it as UrlChanged.js
export default function () {
window.livewire.on('urlChanged', (url) => {
history.pushState(null, null, url);
});
}
Then inside app.js, I’ll just add required files before Alpine.start();
import urlChanged from './UrlChanged.js';
...
Alpine.plugin(urlChanged);
Alpine.start();
After that in your livewire component you can call below method to trigger the emit event like video screenshot.
$this->onChangeRoomTab('route.name', 'tab');