메인 콘텐츠로 건너뛰기

시작하기

Blade는 Laravel에 포함된 단순하면서도 강력한 템플릿 엔진입니다. PHP의 일부 템플릿 엔진과 달리, Blade는 템플릿 내에서 순수 PHP 코드의 사용을 제한하지 않습니다. 모든 Blade 템플릿은 PHP 코드로 컴파일되어 캐시되므로, Blade는 애플리케이션에 거의 오버헤드를 추가하지 않습니다. Blade 템플릿 파일은 .blade.php 확장자를 사용하며, 일반적으로 resources/views 디렉터리에 저장됩니다.

Blade 컴파일 플로우

.blade.php 파일이 어떻게 HTML 응답으로 변환되는지를 보여줍니다. 한 번 컴파일된 파일은 캐시되므로, 동일한 템플릿의 두 번째 이후 요청은 컴파일을 스킵합니다.
Route::get('/', function () {
    return view('greeting', ['name' => '太郎']);
});

데이터 표시

Blade 뷰에 전달된 데이터를 표시하려면 변수를 이중 중괄호로 감쌉니다.
안녕하세요, {{ $name }}.
Blade의 {{ }}는 자동으로 PHP의 htmlspecialchars 함수를 거쳐 XSS 공격을 방지합니다.
변수뿐만 아니라 PHP 함수의 결과도 표시할 수 있습니다.
현재 UNIX 타임스탬프: {{ time() }}

이스케이프하지 않는 데이터 표시

이스케이프를 생략하려면 {!! !!} 문법을 사용합니다.
안녕하세요, {!! $name !!}.
사용자가 입력한 데이터를 표시할 때는 반드시 {{ }}를 사용해 자동 이스케이프를 유효화하십시오. {!! !!}를 신뢰할 수 없는 입력에 사용하면 XSS 취약점으로 이어집니다.

JavaScript 프레임워크와의 공존

JavaScript 프레임워크도 중괄호를 사용하는 경우, @ 심볼로 Blade의 렌더링을 스킵시킵니다.
<h1>Laravel</h1>

안녕하세요, @{{ name }}.
이 경우 @는 Blade에 의해 제거되지만, {{ name }}은 그대로 브라우저에 전송되어 JavaScript 프레임워크에 의해 렌더링됩니다.
Blade를 중심으로 진행할지, Livewire나 Inertia로 넓힐지를 비교하고 싶다면 프런트엔드를 참조하십시오.

Blade 디렉티브

조건 분기(if 문)

@if (count($records) === 1)
    레코드가 1건 있습니다.
@elseif (count($records) > 1)
    여러 레코드가 있습니다.
@else
    레코드가 없습니다.
@endif
@unless로 “~가 아니라면”이라는 조건도 쓸 수 있습니다.
@unless (Auth::check())
    로그인하지 않았습니다.
@endunless
변수가 정의되어 있는지, null이 아닌지를 확인하려면 @isset@empty를 사용합니다.
@isset($records)
    // $records 가 정의되어 있고 null 이 아닌 경우
@endisset

@empty($records)
    // $records 가 "비어 있는" 경우
@endempty

인증 디렉티브

@auth
    // 인증된 사용자용 콘텐츠
@endauth

@guest
    // 미인증 사용자용 콘텐츠
@endguest

Switch 문

@switch($i)
    @case(1)
        첫 번째 케이스...
        @break

    @case(2)
        두 번째 케이스...
        @break

    @default
        기본 케이스...
@endswitch

루프

Blade는 루프를 다루기 위한 편리한 디렉티브를 제공합니다.
@for ($i = 0; $i < 10; $i++)
    현재 값: {{ $i }}
@endfor

@foreach ($users as $user)
    <p>사용자: {{ $user->name }}</p>
@endforeach

@forelse ($users as $user)
    <li>{{ $user->name }}</li>
@empty
    <p>사용자가 없습니다</p>
@endforelse

@while (true)
    <p>영원히 루프합니다.</p>
@endwhile
루프 내에서는 @break@continue를 사용해 루프를 제어할 수 있습니다.
@foreach ($users as $user)
    @if ($user->type == 1)
        @continue
    @endif

    <li>{{ $user->name }}</li>

    @if ($user->number == 5)
        @break
    @endif
@endforeach
조건을 직접 디렉티브에 전달할 수도 있습니다.
@foreach ($users as $user)
    @continue($user->type == 1)

    <li>{{ $user->name }}</li>

    @break($user->number == 5)
@endforeach

루프 변수

@foreach 루프 내에서는 $loop 변수를 사용해 루프에 관한 정보를 취득할 수 있습니다.
@foreach ($users as $user)
    @if ($loop->first)
        첫 번째 반복입니다.
    @endif

    @if ($loop->last)
        마지막 반복입니다.
    @endif

    <p>사용자: {{ $user->name }}</p>
@endforeach
프로퍼티설명
$loop->index현재의 루프 인덱스(0부터 시작)
$loop->iteration현재의 루프 반복 횟수(1부터 시작)
$loop->remaining남은 반복 횟수
$loop->count배열의 요소 수
$loop->first최초의 반복인가
$loop->last마지막 반복인가
$loop->even짝수 번째의 반복인가
$loop->odd홀수 번째의 반복인가
$loop->depth현재의 루프 중첩 깊이
$loop->parent중첩된 루프인 경우, 부모 루프의 변수

코멘트

Blade 코멘트는 렌더링된 페이지에 포함되지 않습니다.
{{-- 이 코멘트는 렌더링된 HTML 에 포함되지 않습니다 --}}

레이아웃

컴포넌트를 사용한 레이아웃

Laravel의 레이아웃 구축에는 Blade 컴포넌트를 사용하는 방법이 권장됩니다. 먼저 레이아웃 컴포넌트를 작성합니다.
<!-- resources/views/components/layout.blade.php -->
<html>
    <head>
        <title>{{ $title ?? '앱 이름' }}</title>
    </head>
    <body>
        <header>
            <nav>
                <!-- 네비게이션 -->
            </nav>
        </header>

        <main>
            {{ $slot }}
        </main>
    </body>
</html>
다음으로 이 레이아웃을 사용하는 뷰를 만듭니다.
<!-- resources/views/dashboard.blade.php -->
<x-layout>
    <x-slot:title>대시보드</x-slot>

    <h1>대시보드</h1>
    <p>어서오세요!</p>
</x-layout>

템플릿 상속을 사용한 레이아웃

고전적인 방법으로 @extends, @section, @yield를 사용한 템플릿 상속이 있습니다. 부모 레이아웃의 정의:
<!-- resources/views/layouts/app.blade.php -->
<html>
    <head>
        <title>앱 이름 - @yield('title')</title>
    </head>
    <body>
        @section('sidebar')
            기본 사이드바
        @show

        <div class="container">
            @yield('content')
        </div>
    </body>
</html>
자식 뷰에서의 레이아웃 상속:
<!-- resources/views/child.blade.php -->
@extends('layouts.app')

@section('title', '자식 페이지')

@section('sidebar')
    @parent

    <p>사이드바에 추가되는 콘텐츠</p>
@endsection

@section('content')
    <p>콘텐츠 본체</p>
@endsection
@parent를 사용하면 부모 레이아웃의 @section 내용을 유지하면서 추가할 수 있습니다.

서브 뷰의 인클루드

@include 디렉티브를 사용하면 Blade 뷰를 다른 뷰에 삽입할 수 있습니다. 부모 뷰에서 사용 가능한 모든 변수는 인클루드된 뷰에서도 사용 가능합니다.
<div>
    @include('shared.errors')

    <form>
        <!-- 폼의 콘텐츠 -->
    </form>
</div>
변수를 추가로 전달할 수도 있습니다.
@include('view.name', ['status' => 'complete'])

폼의 CSRF 보호

web 라우트 파일에서 POST, PUT, PATCH, DELETE 요청을 보내는 HTML 폼에는 반드시 @csrf 디렉티브를 포함시켜 주십시오.
<form method="POST" action="/profile">
    @csrf

    <!-- 폼 필드 -->
</form>
PUT, PATCH, DELETE 요청을 폼에서 보낼 경우 @method 디렉티브를 사용합니다.
<form method="POST" action="/post/1">
    @csrf
    @method('DELETE')

    <button type="submit">삭제</button>
</form>
Origin 검증이나 X-CSRF-TOKEN / X-XSRF-TOKEN 헤더를 포함한 실운용의 CSRF 대책은 CSRF 보호를 참조하십시오.

정리

Blade 템플릿 엔진의 주요 기능을 정리합니다.
{{ $variable }}으로 이스케이프 표시, {!! $variable !!}로 이스케이프 없는 표시.
@if, @elseif, @else, @endif, @unless, @isset, @empty, @auth, @guest.
@for, @foreach, @forelse, @while$loop 변수를 사용한 제어.
컴포넌트 기반(<x-layout>{{ $slot }}) 또는 템플릿 상속(@extends, @section, @yield).
@include로 뷰를 재사용 가능한 파츠로서 삽입.
마지막 수정일 2026년 7월 13일