turbo-laravel icon indicating copy to clipboard operation
turbo-laravel copied to clipboard

Investigate ways of only rendering the layout's content (slot) on Turbo Frame requests

Open tonysm opened this issue 3 years ago • 2 comments

Requests done inside a Turbo Frame have a special Header, such as Turbo-Frame: post_311. By detecting if this header exists, we can programmatically avoid rendering the layout and only render its contents.

One "simple" way of doing this would be to parse the response content and remove only the Turbo Frame it wants from it and return, which would result in less data being sent through the pipes.

However, I think the best way of doing this would be to find a way to not render the layout at all, so we don't spend computational power in there. Also, if users have things like View composer or are making use of lazy-loading relationships and things like that, those wouldn't even execute, to begin with.

tonysm avatar Dec 17 '21 13:12 tonysm

I achieve this in my app by wrapping all my views in an <x-layout> component, and putting logic in that component to determine whether to render the layout vs. just the slot. The component looks like this:

Layout.php:

use Illuminate\View\Component;

class Layout extends Component
{
    public function __construct(public ?string $title = null)
    {
    }

    public function render()
    {
        // If the current request is intended to retrieve the contents of a
        // Turbo Frame, then don't bother rendering the layout chrome.
        if (request()->header('Turbo-Frame')) {
            return '{{ $slot }}';
        }

        return view('components.layout');
    }
}

components/layout.blade.php (simplified):

<!doctype html>
<html>
<head>
    <title>{{ $title }}</title>
</head>
<body>
    {{ $slot }}
</body>
</html>

And then my views all look like this:

<x-layout :title="Hello">
     <h1>This is the page content</h1>
</x-layout>

Not sure how this could be applied in the context of a package, but just posting here in case it sparks some inspiration.

tobyzerner avatar Aug 26 '22 01:08 tobyzerner

@tobyzerner that's exactly how I was thinking this could be solved, but I haven't had the time to test it. Thanks for testing this out!

tonysm avatar Aug 26 '22 14:08 tonysm

Closing this because:

  1. I think the answer shared here is enough
  2. I don't think this is the default way in turbo-rails anymore (and makes sense, as responses for Turbo Frames might return meta tags)

tonysm avatar Jun 02 '23 19:06 tonysm