livewire: Can't change html title dynamically

I have this in the dafule layout: layouts.app’s head tag:

<title>{{ $title ?? config('app.name', 'TITLE') }}</title>

And this in my Livewire component:

<x-slot name="title">mywebsite | search | {{ Str::lower($scope) }}</x-slot>

But it doesn’t change the title of the page when scope is updated.

Context

  • Livewire version: latest
  • Laravel version: latest
  • Browser: Chrome

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 16 (9 by maintainers)

Most upvoted comments

@mokhosh so the reason why we can’t have layout slots updating within Livewire component views like you suggested (at the moment) is that Livewire is “bound” to the main slot in your layout component, not the entire compiled view. If the whole view was sent back each time, this would create an unnecessary performance overhead, and changing the way full-page components work behind the scenes could break component nesting as well. So, when $scope changes and the view is recompiled, only the main slot is sent back to the browser, thus the layout slot does not update.

I’d suggest one of two options…

  • Mount the entire layout as an Alpine component, bind the title with x-text, and use dispatchBrowserEvent() to issue updates to the title.
  • Refresh the page each time your layout needs to update (not ideal UX-wise, but combined with Turbolinks could look pretty seamless).

Hope this helps!

@mokhosh when you are using full page component, you can just use @section('title', 'your title'). in your title tag <title>@yield('title') ?? config('app.name', 'TITLE') }}</title> and your component class use ->extends('layouts.app') instead of ->layout('layouts.app') and you are good to go.

public function render()
{
    return view('livewire.show-posts')->extends('layouts.base');
}

Than for as far as I know only this approach would work:

class ShowPosts extends Component 
{ 
    ... 
    public function render() 
    {   
        return view('livewire.show-posts')
             ->layout('layouts.base', [ 
                  // this is how to pass params to the layout blade component
                  'title' => 'your title' 
             ]); 
    }
}