Fixed: Laravel Blade @else Inside @foreach Syntax Error (Laravel 12 + PHP 8.5)

The problem: You wrote an @else inside an @foreach loop in a Blade template, and instead of rendering, you got a syntax error the moment the page tried to compile.

Environment: Laravel 12, PHP 8.5 (also affects Laravel 9–11 and any recent PHP version — this is a Blade syntax issue, not a version-specific bug)

The Error

ParseError
syntax error, unexpected token "else", expecting end of file

Or, depending on your Laravel/PHP version, you might instead see it surface as a generic 500 error with no clear message, or a blank white screen in local development.

Why It Happens

This is the mistake that causes it — looks completely reasonable at first glance:

@foreach ($items as $item)
    <p>{{ $item->name }}</p>
@else
    <p>No items found.</p>
@endforeach

The reason this breaks: Blade's @foreach directive compiles directly into a plain PHP foreach loop. PHP's native foreach has no concept of an else branch — that syntax simply doesn't exist in PHP, unlike Python's for...else. When Blade compiles your template, it turns your code into something like this behind the scenes:

<?php foreach ($items as $item): ?>
    <p><?php echo $item->name; ?></p>
<?php else: ?>
    <p>No items found.</p>
<?php endforeach; ?>

That's invalid PHP — else can't follow a foreach block on its own — so PHP's parser throws the syntax error before your page ever gets a chance to render.

The Fix

Laravel actually built a directive specifically for this situation: @forelse. It behaves exactly like @foreach, except it lets you define what to show when the collection is empty — no manual if check needed.

@forelse ($items as $item)
    <p>{{ $item->name }}</p>
@empty
    <p>No items found.</p>
@endforelse

Two things changed: @foreach became @forelse, and @else became @empty. The closing tag also changes to @endforelse. That's the entire fix.

Step-by-Step

  1. Find every @foreach block in your Blade files that also contains an @else — search your resources/views folder for @else and check which loop it belongs to.
  2. Rename @foreach to @forelse for that specific block.
  3. Rename the matching @else to @empty.
  4. Rename the closing @endforeach to @endforelse.
  5. Clear Laravel's compiled view cache so the old broken version doesn't linger: run php artisan view:clear in your terminal.
  6. Reload the page — it should render normally now.

Don't confuse this with a regular @if statement wrapping your loop — if you genuinely need conditional logic outside the loop (not tied to whether the collection is empty), keep using a separate @if/@else block around the whole @foreach. @forelse is specifically for the "loop through this, or show a fallback if it's empty" pattern — nothing more.

If you're running a mixed PHP-version setup locally (multiple Laravel projects on different PHP versions in Laragon, for example), this same error can show up looking different depending on how your local server reports parse errors — worth ruling out a version mismatch first if the fix above doesn't immediately resolve it.

Have a different Blade error you're stuck on? Drop it on the Contact page — might turn into the next post.

Advertisement
Advertisement