Skip to content

Use of Button Components With Conditional Blade Directives #57500

@kiusau

Description

@kiusau

Laravel Version

11.44.6

PHP Version

8.2.29

Database Driver & Version

MacOS 15.17.1 in a Homebrew environment.

Description

Title: Blade Parser ParseError: syntax error, unexpected token "endif", expecting end of file with Component in @if Block in Livewire Template (Laravel 11.46.0)Laravel Version: 11.46.0
PHP Version: 8.2.29
Livewire Version: [Specify your Livewire version, e.g., 3.x.x; check with composer show livewire/livewire]
Database Driver & Version: SQLite and MySQL (as per logs)
Operating System: macOS (based on log paths)Description:In a Livewire component, using a Blade component (<x-forms.button>) within an @if block causes a ParseError: syntax error, unexpected token "endif", expecting end of file at the closing @endif of the @if block. The issue occurs only when the Blade component is used; replacing it with a plain resolves the error. The <x-forms.button> component works correctly in other Blade templates outside this specific Livewire context.Steps to Reproduce:Create a Livewire component:php

// app/Livewire/TrailViewer.php
namespace App\Livewire;

use Livewire\Component;

class TrailViewer extends Component
{
public $peak = 1;
public $trek = 24;
public $trail = 144;
public $isCompleted = false;

public function render()
{
    return view('livewire.trail-viewer');
}

}

Create the Livewire template with <x-forms.button> inside an @if block:blade

@if (auth()->check() && auth()->user()->isHiker() && !session('show_trail_viewer', false))
Mark as Read

This trail is {{ $isCompleted ? 'completed!' : 'not yet completed.' }}

@endif

Define the Blade component:blade

<button {{ $attributes }}>{{ $slot }}

Set up a route:php

// routes/web.php
Route::get('/test-trail', \App\Livewire\TrailViewer::class)->middleware(['web', 'auth']);

Ensure a user is authenticated with isHiker() returning true and session('show_trail_viewer', false) set to false.
Access the route (e.g., /test-trail).

Expected Behavior:The template should render a button with the text “Mark as Read” and a paragraph stating “This trail is not yet completed.”, styled according to the classes.Actual Behavior:A ParseError: syntax error, unexpected token "endif", expecting end of file is thrown at the line containing the closing @endif of the outer @if block (line 12 in the example above). The error occurs in the compiled view (storage/framework/views/*.php).Additional Context:Working Cases:Replacing <x-forms.button> with (same attributes and content) resolves the error:blade

<button wire:click.debounce.500ms="markCompleted" class="bg-blue-600 hover:bg-blue-700 {{ $isCompleted ? 'opacity-50 cursor-not-allowed' : '' }}" wire:key="mark-button-{{ $peak }}-{{ $trek }}-{{ $trail }}-{{ auth()->id() }}" {{ $isCompleted ? 'disabled' : '' }}>
Mark as Read

The <x-forms.button> component works in other Blade templates (e.g., non-Livewire contexts or without @if blocks).
Simplifying the @if condition (e.g., @if (auth()->check())) with also works.

Logs:The Livewire component mounts correctly, with variables is_hiker: true, is_completed: false, show_trail_viewer: false, peak: 1, trek: 24, trail: 144.
The error occurs during Blade compilation, pointing to the compiled view’s .

Compiled View (for the working

version):php

check()): ?>
> Mark as Read

This trail is

Error Details:Error: ParseError: syntax error, unexpected token "endif", expecting end of file
File: resources/views/livewire/trail-viewer.blade.php:12
Compiled File: storage/framework/views/*.php:22
Stacktrace points to Livewire\Mechanisms\ExtendBlade\ExtendedCompilerEngine.

Possible Cause:The Blade parser in Laravel 11.46.0 may have a bug when processing a Blade component (<x-forms.button>) inside an @if block within a Livewire template, causing an unexpected state that results in a ParseError at the closing @endif. The issue does not occur with a plain or in non-Livewire contexts, suggesting an interaction between Livewire’s rendering and Blade’s component compilation.Workaround:Inline the button’s content:blade

<button wire:click.debounce.500ms="markCompleted" class="bg-blue-600 hover:bg-blue-700 {{ $isCompleted ? 'opacity-50 cursor-not-allowed' : '' }} bg-gray-600 border-2 border-gray-300 rounded-xl py-2 px-6 font-bold text-white transition-all duration-300 hover:bg-gray-100 hover:!text-gray-800 hover:border-gray-800 hover:border-2" wire:key="mark-button-{{ $peak }}-{{ $trek }}-{{ $trail }}-{{ auth()->id() }}" {{ $isCompleted ? 'disabled' : '' }}>
Mark as Read

Environment:macOS
Laravel 11.46.0
PHP 8.2.29
Livewire [specify version]
Middleware: web, auth, verified, restrict.navigation, handle.session.timeout, payment.status

Additional Notes:Clearing caches (php artisan view:clear, php artisan cache:clear) does not resolve the issue.
The <x-forms.button> component is minimal and works in other templates, indicating a context-specific issue.
Testing with a simpler @if (auth()->check()) condition and works, but <x-forms.button> fails.

Request:
Please investigate if this is a Blade parser bug in Laravel 11.46.0 or a Livewire interaction issue. A fix or guidance on avoiding this error while using Blade components in Livewire templates would be appreciated.

Steps To Reproduce

This report was prepared by Grok at my request. My thanks to Jeffrey Way at Laracasts.com for introducing me to the Laravel framework.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions