본문 바로가기

번역일: 2026년 6월 20일

소개

라우트나 컨트롤러에서 HTML 문자열 전체를 직접 반환하는 것은 현실적이지 않습니다. 뷰를 사용하면 HTML을 별도의 파일로 분리하여 깔끔하게 관리할 수 있습니다.

뷰는 컨트롤러(애플리케이션 로직)와 화면 표현 로직을 분리하는 역할을 하며, resources/views 디렉터리에 저장됩니다. Laravel에서는 주로 Blade 템플릿 언어를 사용해 뷰를 작성합니다. 간단한 뷰 파일의 예는 다음과 같습니다:

<!-- resources/views/greeting.blade.php에 저장된 뷰 --> <html> <body> <h1>안녕하세요, {{ $name }}!</h1> </body> </html>

이 뷰는 resources/views/greeting.blade.php에 저장되어 있으므로, 전역 view 헬퍼 함수를 사용해 다음과 같이 반환할 수 있습니다:

Route::get('/', function () { return view('greeting', ['name' => '홍길동']); });

NOTE

Blade 템플릿 작성법에 대해 더 알고 싶다면 Blade 문서를 참고하세요.

React / Vue로 뷰 작성하기

PHP 기반의 Blade 대신 React나 Vue로 프론트엔드 템플릿을 작성하고 싶은 개발자도 많습니다. Laravel은 Inertia 덕분에 이를 쉽게 구현할 수 있습니다. Inertia는 SPA 구축의 복잡함 없이 React / Vue 프론트엔드를 Laravel 백엔드와 자연스럽게 연결해주는 라이브러리입니다.

스타터 킷인 Breeze와 Jetstream은 Inertia 기반의 Laravel 애플리케이션을 빠르게 시작할 수 있는 훌륭한 출발점을 제공합니다. 또한 Laravel Bootcamp에서는 Vue와 React 예제를 포함하여 Inertia로 Laravel 애플리케이션을 구축하는 전체 과정을 확인할 수 있습니다.

뷰 생성 및 렌더링

뷰는 resources/views 디렉터리에 .blade.php 확장자를 가진 파일을 직접 생성하거나, make:view Artisan 명령어로 생성할 수 있습니다:

php artisan make:view greeting

.blade.php 확장자는 해당 파일이 Blade 템플릿임을 프레임워크에 알립니다. Blade 템플릿에는 HTML과 함께 값 출력, 조건문, 반복문 등을 간결하게 처리할 수 있는 Blade 디렉티브를 사용할 수 있습니다.

뷰 파일을 생성한 후에는 라우트나 컨트롤러에서 전역 view 헬퍼 함수를 사용해 반환합니다:

Route::get('/', function () { return view('greeting', ['name' => '홍길동']); });

View 파사드를 사용해도 동일하게 반환할 수 있습니다:

use Illuminate\Support\Facades\View; return View::make('greeting', ['name' => '홍길동']);

view 헬퍼의 첫 번째 인수는 resources/views 디렉터리 내 뷰 파일의 이름이고, 두 번째 인수는 뷰에 전달할 데이터 배열입니다. 위 예제에서는 name 변수를 전달하며, 뷰에서 Blade 문법으로 출력합니다.

중첩 뷰 디렉터리

뷰 파일은 resources/views 디렉터리 안의 하위 디렉터리에 중첩하여 저장할 수 있습니다. 중첩된 뷰를 참조할 때는 .(점) 표기법을 사용합니다. 예를 들어 뷰가 resources/views/admin/profile.blade.php에 저장되어 있다면 다음과 같이 반환합니다:

return view('admin.profile', $data);

WARNING

뷰 디렉터리 이름에는 . 문자를 포함할 수 없습니다.

존재하는 첫 번째 뷰 반환하기

View 파사드의 first 메서드를 사용하면 주어진 뷰 배열 중 실제로 존재하는 첫 번째 뷰를 반환할 수 있습니다. 애플리케이션이나 패키지에서 뷰를 커스터마이징하거나 덮어쓸 수 있도록 허용할 때 유용합니다:

use Illuminate\Support\Facades\View; return View::first(['custom.admin', 'admin'], $data);

뷰 존재 여부 확인

특정 뷰가 존재하는지 확인해야 할 때는 View 파사드의 exists 메서드를 사용합니다. 뷰가 존재하면 true를 반환합니다:

use Illuminate\Support\Facades\View; if (View::exists('admin.profile')) { // ... }

뷰에 데이터 전달하기

앞선 예제에서 보았듯이, 배열 형태로 데이터를 뷰에 전달할 수 있습니다:

return view('greetings', ['name' => '이순신']);

이 방식으로 데이터를 전달하면 배열의 각 키가 뷰 안에서 변수로 사용됩니다. 예를 들어 <?php echo $name; ?>과 같이 접근할 수 있습니다.

배열 전체를 한 번에 전달하는 대신, with 메서드를 사용해 데이터를 하나씩 추가할 수도 있습니다. with 메서드는 뷰 객체 인스턴스를 반환하므로 메서드를 체이닝하여 계속 이어서 호출할 수 있습니다:

return view('greeting') ->with('name', '이순신') ->with('occupation', '장군');

모든 뷰에 데이터 공유하기

애플리케이션에서 렌더링되는 모든 뷰에 동일한 데이터를 공유해야 할 때가 있습니다. 예를 들어 로그인한 사용자 정보나 사이트 설정값처럼 어느 뷰에서나 필요한 데이터가 이에 해당합니다. 이런 경우 View 파사드의 share 메서드를 사용합니다.

share 메서드 호출은 보통 서비스 프로바이더의 boot 메서드 안에 작성합니다. App\Providers\AppServiceProvider에 추가하거나, 별도의 서비스 프로바이더를 생성해 관리할 수 있습니다:

<?php namespace App\Providers; use Illuminate\Support\Facades\View; class AppServiceProvider extends ServiceProvider { /** * 애플리케이션 서비스를 등록합니다. */ public function register(): void { // ... } /** * 애플리케이션 서비스를 부트스트랩합니다. */ public function boot(): void { View::share('key', 'value'); } }

뷰 컴포저

뷰 컴포저는 뷰가 렌더링될 때 호출되는 콜백 또는 클래스 메서드입니다. 특정 뷰가 렌더링될 때마다 항상 특정 데이터를 바인딩해야 한다면, 뷰 컴포저를 사용하면 해당 로직을 한 곳에 모아 관리할 수 있습니다. 여러 라우트나 컨트롤러에서 동일한 뷰를 반환하고, 매번 같은 데이터가 필요한 경우에 특히 유용합니다.

뷰 컴포저는 "이 뷰가 그려질 때마다 이 데이터를 자동으로 넣어줘"라고 등록해두는 방식입니다. 반복적인 데이터 바인딩 코드를 줄이는 데 효과적입니다.

뷰 컴포저는 일반적으로 서비스 프로바이더 안에서 등록합니다. 여기서는 App\Providers\AppServiceProvider를 사용하겠습니다.

View 파사드의 composer 메서드로 뷰 컴포저를 등록합니다. Laravel은 클래스 기반 뷰 컴포저를 위한 기본 디렉터리를 따로 제공하지 않으므로, 원하는 방식으로 구성할 수 있습니다. 예를 들어 app/View/Composers 디렉터리를 만들어 관리하는 것이 일반적입니다:

<?php namespace App\Providers; use App\View\Composers\ProfileComposer; use Illuminate\Support\Facades; use Illuminate\Support\ServiceProvider; use Illuminate\View\View; class AppServiceProvider extends ServiceProvider { /** * 애플리케이션 서비스를 등록합니다. */ public function register(): void { // ... } /** * 애플리케이션 서비스를 부트스트랩합니다. */ public function boot(): void { // 클래스 기반 컴포저 등록 Facades\View::composer('profile', ProfileComposer::class); // 클로저 기반 컴포저 등록 Facades\View::composer('welcome', function (View $view) { // ... }); Facades\View::composer('dashboard', function (View $view) { // ... }); } }

컴포저를 등록하면 profile 뷰가 렌더링될 때마다 App\View\Composers\ProfileComposer 클래스의 compose 메서드가 자동으로 실행됩니다. 컴포저 클래스의 예는 다음과 같습니다:

<?php namespace App\View\Composers; use App\Repositories\UserRepository; use Illuminate\View\View; class ProfileComposer { /** * 새 프로필 컴포저 인스턴스를 생성합니다. */ public function __construct( protected UserRepository $users, ) {} /** * 뷰에 데이터를 바인딩합니다. */ public function compose(View $view): void { $view->with('count', $this->users->count()); } }

모든 뷰 컴포저는 서비스 컨테이너를 통해 의존성이 해결되므로, 컴포저의 생성자에서 필요한 의존성을 타입 힌트로 선언할 수 있습니다.

여러 뷰에 컴포저 연결하기

composer 메서드의 첫 번째 인수로 뷰 이름 배열을 전달하면, 여러 뷰에 동시에 컴포저를 연결할 수 있습니다:

use App\Views\Composers\MultiComposer; use Illuminate\Support\Facades\View; View::composer( ['profile', 'dashboard'], MultiComposer::class );

* 와일드카드를 사용하면 모든 뷰에 컴포저를 적용할 수도 있습니다:

use Illuminate\Support\Facades; use Illuminate\View\View; Facades\View::composer('*', function (View $view) { // ... });

뷰 크리에이터

뷰 크리에이터는 뷰 컴포저와 매우 유사하지만, 뷰가 렌더링되기 직전이 아닌 인스턴스화된 직후 즉시 실행된다는 점이 다릅니다. 뷰 크리에이터를 등록할 때는 creator 메서드를 사용합니다:

use App\View\Creators\ProfileCreator; use Illuminate\Support\Facades\View; View::creator('profile', ProfileCreator::class);

뷰 최적화

기본적으로 Blade 템플릿은 요청이 들어올 때 필요에 따라 컴파일됩니다. 뷰를 렌더링하는 요청이 실행되면, Laravel은 해당 뷰의 컴파일된 버전이 존재하는지 확인합니다. 컴파일된 파일이 없거나 원본 뷰 파일이 컴파일된 파일보다 최근에 수정되었다면, Laravel이 뷰를 다시 컴파일합니다.

이처럼 요청 처리 중에 뷰를 컴파일하면 성능에 약간의 영향을 줄 수 있습니다. 이를 방지하기 위해 view:cache Artisan 명령어로 애플리케이션에서 사용하는 모든 뷰를 미리 컴파일해둘 수 있습니다. 배포 과정에 이 명령어를 포함시키면 성능을 향상시킬 수 있습니다:

php artisan view:cache

뷰 캐시를 삭제하려면 view:clear 명령어를 사용합니다:

php artisan view:clear

이 문서는 Laravel 공식 문서(MIT)를 한국 개발자를 위해 번역·재구성한 것입니다.

번역일: 2026년 6월 20일