Laravel Head
- Introduction
- Installation
- Quickstart
- Resolution Precedence
- Defining Metadata
- Open Graph
- Theme Colors
- Application Metadata and Icons
- Progressive Web Apps
- Performance and Discovery
- Custom Tags
- Schemas
- Rendering
Introduction
Laravel Head는 애플리케이션의 문서 <head> 요소를 관리하기 위한 유연한 API를 제공합니다. 여기에는 제목 및 메타 태그, Open Graph 메타데이터, 표준 URL, robots 지시문, 성능 힌트, 구조화된 데이터가 포함됩니다. Blade, Livewire, Inertia와 함께 사용할 수 있습니다.
Installation
Composer 패키지 관리자를 사용해 Laravel Head를 설치할 수 있습니다.
composer require laravel/head
Quickstart
서비스 전체 기본값을 서비스 프로바이더에 등록합니다:
use Laravel\Head\Facades\Head;
use Laravel\Head\HeadBuilder;
Head::defaults(fn (HeadBuilder $head) => $head
->title('Laravel', suffix: ' - Laravel')
->description('Build something great.'));
런타임에 페이지별 메타데이터를 설정합니다:
Head::title($post->title)
->description($post->description);
레이아웃에 확인된 태그를 렌더링합니다:
<head>
@head
</head>
Resolution Precedence
페이지 메타데이터는 우선순위가 낮은 계층부터 높은 계층 순으로 나열된 다음 다섯 계층에서 확인됩니다:
- 페이지 기본값
- 라우트 그룹 메타데이터
- 라우트 메타데이터
- 런타임 메타데이터
- 오류 메타데이터
상위 레이어는 필드별로 하위 레이어를 대체합니다. 예를 들어 런타임 제목은 라우트 설명을 대체하지 않고 라우트 제목을 대체합니다. 이어지는 섹션에서는 각 레이어에서 메타데이터를 설정하는 방법을 설명합니다. Blade, Livewire, Inertia에서 확인된 메타데이터를 렌더링하는 방법은 Rendering을 참고하세요.
Defining Metadata
Laravel Head를 사용하면 사이트 전체 기본값, 라우트 메타데이터, 런타임 호출 및 오류 페이지 정의를 사용해 메타데이터를 정의할 수 있습니다.
Defaults
서비스 프로바이더에서 페이지 기본값을 등록합니다:
use Laravel\Head\Enums\OgType;
use Laravel\Head\Facades\Head;
use Laravel\Head\HeadBuilder;
Head::defaults(function (HeadBuilder $head) {
$head
->title('Laravel', suffix: ' - Laravel')
->description('Build something great.')
->canonical()
->og(siteName: 'Laravel', type: OgType::Website)
->searchableByRobots()
->preconnect('https://fonts.example.com');
});
Defaults는 페이지 메타데이터 계층 중 우선순위가 가장 낮습니다. 라우트, 런타임 또는 오류 메타데이터에서 제목을 설정하지 않으면 Laravel이 있는 그대로 렌더링됩니다. 더 높은 계층에서 페이지 제목을 설정하면 상속된 접미사가 적용되므로 Head::title('About')은 About - Laravel로 렌더링됩니다. 상속된 접두사 또는 접미사를 무시해야 하는 제목에는 exact: true를 전달합니다.
Head::canonical()을 호출하면 현재 요청 URL을 사용해 canonical URL을 렌더링합니다. 명시적인 URL을 설정하려면 Head::canonical('/about')와 같이 문자열을 전달합니다. canonical URL은 기본적으로 https로 정규화되며, 요청 스킴을 유지하려면 forceHttps: false를 전달합니다.
Robots 지시어는 원시 문자열, RobotsRule 열거형 케이스 또는 두 형식을 혼합한 목록으로 전달할 수 있습니다. 목록은 쉼표로 구분된 지시어로 렌더링되므로 Head::robots([RobotsRule::NoIndex, RobotsRule::NoFollow])는 noindex, nofollow로 렌더링됩니다.
편의를 위해 searchableByRobots 메서드는 all을 렌더링하고 hiddenFromRobots 메서드는 none을 렌더링합니다.
Route Metadata
라우트에 메타데이터를 직접 정의할 수 있으며, 이는 메타데이터를 미리 알고 있는 반정적 페이지에 특히 유용합니다.
Routes and Groups
Route::view('/contact', 'contact')
->name('contact')
->withHead(
title: 'Contact Us',
description: 'Get in touch.',
);
공유 라우트 메타데이터는 체인의 어느 위치에서든 그룹에 적용할 수 있습니다:
Route::withHead(robots: 'noindex, nofollow')
->prefix('admin')
->name('admin.')
->group(function () {
Route::get('/dashboard', DashboardController::class)
->name('dashboard')
->withHead(title: 'Dashboard');
});
리소스 및 싱글턴 라우트에 대한 메타데이터도 정의할 수 있습니다.
Route::resource('posts', PostController::class)->withHead(
robots: 'index, follow',
);
Route::singleton('profile', ProfileController::class)->withHead(
title: 'Your Profile',
);
withHead 메서드는 Laravel의 네이티브 라우트 메타데이터 API를 통해 일반 배열을 저장합니다. 이는 head 키 아래에 속성을 중첩하여 metadata 메서드를 호출하는 것과 동일하므로, 메타데이터가 캐시된 라우트와의 호환성을 유지합니다.
이름이 지정된 인수는 편집기와 정적 분석 도구가 철자가 틀린 이름을 감지할 수 있도록 Laravel Head에 내장된 라우트 속성으로 의도적으로 제한되어 있습니다. 사용자 지정 태그 빌더에 등록된 라우트 속성은 extensions를 통해 전달할 수 있습니다.
Route::get('/article', ArticleController::class)->withHead(
title: 'Article',
extensions: ['readingTime' => 4],
);
Supported Properties
지원되는 라우트 속성은 fluent builder 메서드와 동일한 이름으로 매핑됩니다:
| 카테고리 | 속성 |
|---|---|
| 문서 | title, description, canonical, robots |
| 애플리케이션 메타데이터 | themeColor, applicationName, colorScheme, referrer, viewport, appleWebAppTitle, webAppCapable, appleWebAppStatusBarStyle |
| 소셜 | og, ogImage, ogVideo, ogAudio, twitter, twitterImage |
| 성능 | preload, prefetch, preconnect, dnsPrefetch |
| 검색 | alternates, feed, icon, favicon, appleTouchIcon, appleTouchStartupImage, maskIcon, manifest |
| 구조화된 데이터 | schema |
| 사용자 지정 태그 | meta, link |
중첩 옵션 이름은 fluent API와 동일한 camelCase 명명 규칙을 사용합니다. 예를 들어 forceHttps, siteName, secureUrl이 있습니다.
ogImage, preload, feed, schema, icon, appleTouchStartupImage와 같은 반복 가능한 속성은 단일 값이나 목록을 사용할 수 있습니다.
Runtime Metadata
요청이 들어올 때까지 값을 알 수 없는 경우, 예를 들어 조회 중인 게시물의 제목과 같은 값은 런타임에 설정할 수 있습니다:
use Laravel\Head\Facades\Head;
public function __invoke(Post $post): Response
{
Head::title($post->title);
// ...
}
Head 파사드를 통해 수행되는 런타임 호출은 요청에 의존하는 데이터의 라우트 메타데이터를 재정의합니다. 컨트롤러와 액션은 이러한 호출을 수행하는 가장 일반적인 위치입니다:
use App\Models\Post;
use Laravel\Head\Facades\Head;
public function show(Post $post)
{
Head::title($post->title)
->description($post->description);
return view('posts.show', ['post' => $post]);
}
여러 런타임 호출은 실행되는 순서대로 병합됩니다. title, description, canonical URL, robots 지시어와 같은 단일 값 필드에서는 나중에 호출된 값이 우선합니다. 반복 가능한 필드는 여러 항목을 유지하지만, 동일한 키를 다시 추가하면 앞서 추가된 항목이 업데이트됩니다. ogImage 메서드에서는 URL이 키입니다:
Head::ogImage('/images/cover.jpg', alt: 'Draft cover')
->ogImage('/images/gallery.jpg', alt: 'Gallery image')
->ogImage('/images/cover.jpg', alt: 'Final cover', width: 1200, height: 630);
<meta property="og:image" content="/images/cover.jpg">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta property="og:image:alt" content="Final cover">
<meta property="og:image" content="/images/gallery.jpg">
<meta property="og:image:alt" content="Gallery image">
기본 설정에서 상속된 Open Graph 미디어는 대체 수단으로 사용됩니다. 라우트, 런타임 또는 오류 메타데이터가 동일한 타입의 미디어를 자체적으로 정의하면 기본 미디어는 병합되지 않고 대체되므로, 페이지의 og:image가 사이트 전체의 기본 이미지보다 우선합니다.
when 및 unless 메서드를 사용하면 조건부 메타데이터를 유창하게 정의할 수 있습니다:
Head::title($post->title)
->when($post->isDraft(), fn ($head) => $head->hiddenFromRobots());
Error Pages
일반적으로 애플리케이션의 AppServiceProvider 클래스에서 boot 메서드 내에 오류 메타데이터를 등록해야 합니다:
use Laravel\Head\ErrorPages;
use Laravel\Head\Facades\Head;
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Head::errors(function (ErrorPages $errors) {
$errors->defaults(robots: 'noindex, follow');
$errors->status(
404,
title: 'Page Not Found',
description: 'The page you are looking for could not be found.',
);
});
}
defaults 및 status 메서드도 Head::defaults()에서 사용하는 것과 동일한 플루언트 빌더 콜백을 허용합니다:
use Laravel\Head\ErrorPages;
use Laravel\Head\Facades\Head;
use Laravel\Head\HeadBuilder;
Head::errors(function (ErrorPages $errors) {
$errors->status(404, fn (HeadBuilder $head) => $head
->title('Page Not Found')
->description('The page you are looking for could not be found.'));
});
응답이 등록된 오류 상태로 렌더링되면 해당 메타데이터가 다른 모든 계층보다 우선합니다.
Laravel은 오류 뷰를 렌더링하거나 Inertia의 handleExceptionsUsing() 메서드와 같은 응답 단계 훅을 실행할 때 응답 상태를 자동으로 감지합니다. $exceptions->render() 콜백 내부에서 오류 응답을 렌더링한다면, 렌더링하기 전에 Head::status(404)를 호출하여 오류 메타데이터가 적용되도록 해야 합니다.
Open Graph
og 메서드를 사용해 Open Graph 속성을 설정할 수 있습니다. 반복 가능한 미디어는 이름이 지정된 인수를 직접 받는 최상위 메서드를 사용해 추가할 수 있습니다:
use Laravel\Head\Enums\ImageType;
use Laravel\Head\Enums\OgType;
Head::og(type: OgType::Article, title: $post->title)
->ogImage($post->hero_image_url)
->ogImage(
$post->gallery_image_url,
alt: $post->gallery_image_alt,
width: 1200,
height: 630,
type: ImageType::Jpeg,
);
ogImage, ogVideo, ogAudio 메서드는 첫 번째 인수로 URL을 받으며, Open Graph 사양에서 지원하는 경우 alt, width, height, type, secureUrl와 같은 선택적 명명 인수도 받습니다.
이미지 type을 허용하는 API의 모든 곳에서 ImageType::Svg, ImageType::Png, ImageType::Jpeg, ImageType::Webp와 같은 ImageType enum 케이스로 이미지 MIME 타입을 전달할 수 있습니다.
문서의
title과description은 누락된og:title과og:description값을 자동으로 채웁니다.
다른 속성 없이 Open Graph 이미지 하나만 지정하려면 og 메서드에 image 이름 지정 인수를 전달할 수 있습니다:
Head::og(
type: OgType::Website,
title: $page->title,
description: $page->description,
image: $page->og_image_url,
);
og(image: ...) 및 ogImage(...) 호출은 동일한 내부 이미지 목록에 기록하므로, 호출 위치에서 더 표현력이 높은 방식을 사용하면 됩니다. 제품 또는 문서 속성과 같은 사용자 지정 Open Graph 확장에는 meta 메서드를 사용할 수 있습니다.
X / Twitter Cards
Open Graph에 사용하는 것과 동일한 제목, 설명, 이미지를 사용해 X / Twitter 카드를 렌더링하려면 기본값에 twitter()를 등록합니다:
use Laravel\Head\Enums\TwitterCard;
use Laravel\Head\Facades\Head;
use Laravel\Head\HeadBuilder;
Head::defaults(fn (HeadBuilder $head) => $head->twitter(
card: TwitterCard::SummaryWithLargeImage,
));
그런 다음 페이지 수준 메타데이터를 설정합니다:
Head::title('Introducing Laravel Head')
->description('A fluent API for Laravel document head metadata.')
->ogImage('https://example.com/social.jpg', alt: 'Introducing Laravel Head');
다음은 일치하는 Twitter 태그를 렌더링합니다:
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Introducing Laravel Head">
<meta name="twitter:description" content="A fluent API for Laravel document head metadata.">
<meta name="twitter:image" content="https://example.com/social.jpg">
<meta name="twitter:image:alt" content="Introducing Laravel Head">
개별 페이지에 명시적인 Twitter 값을 지정할 수 있습니다:
Head::twitter(title: $post->social_title)
->twitterImage($post->social_image_url, alt: $post->title);
라우트 메타데이터는 twitter와 twitterImage를 허용합니다.
Theme Colors
테마 색상은 전역, 라우트별 또는 런타임에 설정할 수 있습니다:
Head::themeColor('#0f172a');
<meta name="theme-color"> 태그를 렌더링합니다. 미디어별 테마 색상에는 Media enum을 사용할 수 있습니다:
use Laravel\Head\Enums\Media;
Head::themeColor('#ffffff', media: Media::Light)
->themeColor('#111827', media: Media::Dark);
Media enum에는 Portrait와 Landscape도 포함되어 있습니다. media 인수에는 사용자 지정 미디어 쿼리 문자열도 전달할 수 있습니다.
라우트 메타데이터는 동일한 camelCase 키를 통해 하나의 테마 색상을 지원합니다:
Route::view('/dashboard', 'dashboard')->withHead(
themeColor: '#0f172a',
);
Application Metadata and Icons
Laravel Head에는 자주 사용하는 브라우저 및 애플리케이션 메타데이터를 위한 메서드가 포함되어 있습니다:
use Laravel\Head\Enums\ImageType;
use Laravel\Head\Enums\Media;
Head::applicationName('Laravel')
->colorScheme('light dark')
->referrer('strict-origin-when-cross-origin')
->viewport('width=device-width, initial-scale=1')
->appleWebAppTitle('Laravel')
->webAppCapable()
->appleWebAppStatusBarStyle('black')
->favicon('/favicon.svg', type: ImageType::Svg)
->icon('/favicon-32x32.png', type: ImageType::Png, sizes: '32x32')
->appleTouchIcon('/apple-touch-icon.png', sizes: '180x180')
->appleTouchStartupImage('/launch.png', media: Media::Portrait)
->maskIcon('/safari-pinned-tab.svg', color: '#111827')
->manifest('/site.webmanifest');
favicon 메서드는 icon 메서드의 별칭이며 동일한 type, sizes, media 인수를 받습니다.
라우트 메타데이터는 동일한 이름을 사용합니다:
use Laravel\Head\Enums\ImageType;
use Laravel\Head\Enums\Media;
Route::view('/dashboard', 'dashboard')->withHead(
applicationName: 'Laravel',
colorScheme: 'light dark',
appleWebAppTitle: 'Laravel',
webAppCapable: true,
appleWebAppStatusBarStyle: 'black',
favicon: [
['href' => '/favicon.svg', 'type' => ImageType::Svg],
['href' => '/favicon-32x32.png', 'type' => ImageType::Png, 'sizes' => '32x32'],
],
appleTouchIcon: ['href' => '/apple-touch-icon.png', 'sizes' => '180x180'],
appleTouchStartupImage: ['href' => '/launch.png', 'media' => Media::Portrait],
manifest: '/site.webmanifest',
);
Progressive Web Apps
pwa 메서드는 설치 가능한 웹 앱에 필요한 일반적인 문서 <head> 태그를 설정합니다:
Head::pwa(
name: 'Laravel',
manifest: '/site.webmanifest',
themeColor: '#0f172a',
appleTouchIcon: '/apple-touch-icon.png',
appleWebAppStatusBarStyle: 'black',
);
애플리케이션 이름, 웹 애플리케이션 매니페스트 링크, iOS 독립 실행형 메타데이터를 렌더링합니다. 제공된 경우 테마 색상, Apple 상태 표시줄 스타일, Apple 터치 아이콘도 렌더링합니다. 웹 애플리케이션 매니페스트를 생성하고 서비스 워커를 등록하는 일은 애플리케이션의 책임입니다.
defaults 또는 runtime metadata에서 pwa 메서드를 사용할 수 있습니다. 라우트 메타데이터는 위에 설명된 개별 프로퍼티를 지원합니다.
Performance and Discovery
Laravel Head는 성능 힌트, 페이지네이션 링크, 로케일 대체 링크, 피드 검색 정보를 렌더링합니다:
Head::preload(asset('fonts/inter.woff2'), as: 'font', crossorigin: true)
->prefetch(asset('images/next.webp'))
->preconnect('https://cdn.example.com')
->dnsPrefetch('https://analytics.example.com')
->paginate($posts)
->alternates([
'en' => 'https://example.com/en/about',
'fr' => 'https://example.com/fr/about',
'x-default' => 'https://example.com/about',
])
->feed('/feed', title: 'Laravel RSS')
->feed('/feed.atom', type: 'atom', title: 'Laravel Atom');
로컬 에셋의 경우 preloadAsset() 및 prefetchAsset()는 asset() 헬퍼를 통해 URL을 확인하고 파일 확장자에서 as 속성을 감지합니다. 글꼴 프리로드에는 동일 출처 글꼴에도 프리로드 사양에서 요구하는 crossorigin이 자동으로 포함됩니다:
Head::preloadAsset('fonts/inter.woff2')
->prefetchAsset('images/next.webp');
<link rel="preload" href="https://example.com/fonts/inter.woff2" as="font" crossorigin>
<link rel="prefetch" href="https://example.com/images/next.webp" as="image">
as를 명시적으로 전달하여 감지를 재정의할 수 있습니다. 브라우저는 이 속성이 없는 preload를 무시하므로, 확장자에서 as 속성을 감지할 수 없으면 preloadAsset 메서드는 예외를 발생시키며 prefetchAsset 메서드는 해당 속성을 생략합니다.
Custom Tags
전용 메서드가 없는 태그에는 meta()와 link()를 사용합니다:
Head::meta('format-detection', 'telephone=no')
->meta('article:author', $post->author->name)
->link('search', '/opensearch.xml', [
'type' => 'application/opensearchdescription+xml',
'title' => 'Laravel Search',
])
->link('me', 'https://social.example.com/@laravel');
브라우저가 일치하는 조건에서만 해당 태그를 적용해야 한다면 meta 태그에 미디어 쿼리를 포함할 수 있습니다:
use Laravel\Head\Enums\Media;
Head::meta('theme-color', '#ffffff', media: Media::Light)
->meta('theme-color', '#111827', media: Media::Dark);
meta 메서드는 일반 메타 태그에 name 속성을 사용합니다. Open Graph(og:)나 아티클 메타데이터(article:)처럼 일반적으로 property 속성을 사용하는 키의 경우 메서드가 자동으로 전환합니다:
Head::meta('description', 'About Laravel')
->meta('og:title', 'About Laravel');
<meta name="description" content="About Laravel">
<meta property="og:title" content="About Laravel">
property: true 또는 property: false를 전달해 속성을 명시적으로 선택할 수 있습니다.
Schemas
내장 스키마 빌더는 일반적인 JSON-LD 타입을 다룹니다:
use Laravel\Head\Enums\OfferAvailability;
use Laravel\Head\Facades\Schema;
Head::schema(
Schema::product()
->name($product->name)
->offers(
Schema::offer()
->price($product->price)
->currency('USD')
->availability(OfferAvailability::InStock)
)
);
기본 제공 팩토리 메서드는 article, blogPosting, product, offer, brand, breadcrumbs, faq, organization, person, webPage, webSite입니다. 알 수 없는 팩토리 메서드는 일반 스키마 객체를 생성하므로, 사용자 지정 schema.org 타입도 표현할 수 있습니다.
JSON-LD 스키마 데이터가 유효하지 않으면 Laravel Head는 프로덕션 환경이 아닌 환경에서 예외를 발생시키고, 프로덕션에서는 경고를 기록합니다.
Breadcrumbs
Breadcrumb 항목은 하나씩 추가하거나 한 번에 여러 개 추가할 수 있습니다. 위치는 항목을 추가한 순서에 따라 자동으로 할당됩니다.
Head::schema(
Schema::breadcrumbs()->items([
'Home' => route('home'),
'Shop' => route('shop.index'),
'Shoes' => route('shop.category', 'shoes'),
])
);
단일 브레드크럼 항목을 추가하려면 item 메서드를 사용할 수 있습니다:
Schema::breadcrumbs()
->item('Home', route('home'))
->item('Shop', route('shop.index'));
FAQs
FAQ 항목도 같은 패턴을 따릅니다. question 메서드를 사용해 하나씩 추가하거나 questions 메서드를 사용해 일괄적으로 추가할 수 있습니다.
Head::schema(
Schema::faq()->questions([
'What is Laravel Head?' => 'A fluent API for managing the document head.',
'Is it free?' => 'Yes, it is open source.',
])
);
Custom Schemas
사용자 지정 스키마 타입을 명시적으로 등록할 수도 있습니다:
use DateTimeInterface;
use Laravel\Head\Facades\Schema;
use Laravel\Head\Schema\SchemaObject;
use Laravel\Head\SchemaType;
#[SchemaType('JobPosting')]
class JobPosting extends SchemaObject
{
public function title(string $title): static
{
return $this->set('title', $title);
}
public function datePosted(DateTimeInterface|string $date): static
{
return $this->date('datePosted', $date);
}
}
Schema::register(JobPosting::class);
Head::schema(
Schema::jobPosting()
->title('Senior Laravel Developer')
->datePosted(now())
);
Rendering
Laravel Head는 현재 응답의 페이지 메타데이터를 태그로 변환합니다. 이러한 태그가 렌더링되는 방식은 애플리케이션 스택에 따라 달라집니다.
HTML 렌더러는 @head 디렉티브와 Laravel Head가 head 프로퍼티를 통해 Inertia와 공유하는 렌더링된 요소를 처리합니다. 배열 렌더러는 확인된 메타데이터를 구조화된 데이터로 사용해야 하는 애플리케이션을 위해 Head::toArray()를 처리합니다.
Blade
레이아웃의 <head>에 @head 디렉티브를 사용해 누적된 태그를 렌더링합니다:
<head>
<meta charset="utf-8">
@head
</head>
@head 디렉티브는 동기적으로 렌더링되므로 레이아웃이 렌더링되기 전에 페이지 메타데이터를 정의해야 합니다.
Livewire
Livewire 애플리케이션은 문서 레이아웃에서 동일한 @head 디렉티브를 사용합니다:
<head>
@head
</head>
<body>
{{ $slot }}
@livewireScripts
</body>
Livewire 전용 설정은 필요하지 않습니다. Laravel Head 메타데이터는 요청마다 확인되며, resolver는 요청 범위로 동작합니다. 따라서 각 wire:navigate 방문은 대상 라우트의 메타데이터가 반영된 @head 출력을 포함하는 새로운 문서를 가져옵니다. wire:navigate를 사용해 방문한 페이지는 컴포넌트 수준의 head 코드 없이 적절한 라우트, 런타임 및 오류 메타데이터를 받습니다.
Inertia
Inertia의 자체 컴포넌트와 함께 Inertia 루트 템플릿에서도 동일한 @head 디렉티브를 사용합니다:
<html>
<head>
<meta charset="utf-8">
@head
@viteReactRefresh
@vite(['resources/css/app.css', 'resources/js/app.tsx'])
<x-inertia::head />
</head>
<body>
<x-inertia::app />
</body>
</html>
Inertia를 설치하면 Laravel Head는 페이지에서 관리하는 head를 렌더링된 요소 문자열의 배열로 자동 공유하며, 모든 페이지 객체에서 head prop으로 사용할 수 있도록 합니다:
{
"props": {
"head": [
"<title data-inertia=\"title\">Dashboard - Laravel</title>",
"<meta data-inertia=\"description\" name=\"description\" content=\"Your application overview.\">"
]
}
}
애플리케이션에서 createInertiaApp()을 호출하는 모든 곳에서 Inertia의 serverHead 옵션을 활성화합니다. 이 옵션은 Inertia 3.5 이상에서 사용할 수 있습니다.
createInertiaApp({
// ...
serverHead: true,
});
각 페이지 관리 요소에는 안정적인 data-inertia 키가 있습니다. @head 디렉티브는 초기 문서를 렌더링하며, 이후 Inertia는 해당 요소를 관리하고 일반 방문, instant visits, 뒤로 가기 및 앞으로 가기 탐색 중에 요소를 동기화된 상태로 유지합니다. 요소는 초기 HTML 응답에 포함되므로 크롤러와 링크 미리보기 봇은 JavaScript를 실행하지 않고도 요소를 읽을 수 있습니다. 클라이언트 측 <Head> 컴포넌트는 필요하지 않습니다.
이는 server-side rendering (SSR) 여부와 관계없이 작동합니다. 애플리케이션에 별도의 SSR 진입점이 있다면 해당 진입점에서도 serverHead를 활성화해야 합니다. Laravel Head는 순서와 관계없이 @head와 <x-inertia::head /> 사이에서 페이지가 관리하는 요소의 중복을 자동으로 제거하면서, JavaScript SSR이 생성한 다른 head 요소는 그대로 유지합니다.
기존 Inertia 애플리케이션에 Laravel Head를 추가할 때는
resources/js/app.tsx와resources/js/ssr.tsx에서 모든 title 콜백을 제거하여 Laravel Head가 최종 문서 제목을 관리하도록 해야 합니다. 또한 Inertia의<Head>component가 관리하는 태그를 Laravel Head로 옮겨 두 도구가 동일한 요소를 정의하지 않도록 해야 합니다.
부분 재로드 응답에서는 head prop이 생략되므로 Inertia는 마지막 전체 페이지의 head를 유지합니다. 즉시 방문에서도 백그라운드 응답이 도착할 때까지 현재 head를 유지합니다. 애플리케이션에서 이미 head prop을 사용하고 있다면 서비스 프로바이더에서 이름을 변경합니다:
use Laravel\Head\Facades\Head;
public function boot(): void
{
Head::inertia(prop: '_head');
}
그런 다음 serverHead: '_head'를 사용해 Inertia가 동일한 prop을 가리키도록 설정합니다.
Static Inertia Tags
대부분의 태그는 기본값, 라우트 메타데이터 또는 런타임 메타데이터에 정의해야 Laravel Head가 각 페이지에 맞는 값을 확인할 수 있습니다. Inertia 전역 변수는 첫 번째 HTML 응답에서 렌더링되고 나머지 세션 동안 Inertia가 변경하지 않는 문서 태그에만 사용하세요.
서비스 프로바이더에서 Head::inertiaGlobals()를 사용해 등록합니다:
use Laravel\Head\Facades\Head;
use Laravel\Head\HeadBuilder;
Head::inertiaGlobals(function (HeadBuilder $head) {
$head
->viewport('width=device-width, initial-scale=1')
->colorScheme('light dark')
->icon('/favicon.svg', type: 'image/svg+xml')
->appleTouchIcon('/apple-touch-icon.png', sizes: '180x180')
->manifest('/site.webmanifest');
});
Inertia 전역은 head prop에서 제외되고 data-inertia 소유권 속성 없이 렌더링되며 첫 번째 응답 이후에는 업데이트되지 않습니다. 이러한 전역은 뷰포트, 색 구성표, 파비콘, 터치 아이콘, 매니페스트처럼 안정적인 브라우저 힌트에 적합합니다. 태그가 페이지별로 다르거나 SEO와 관련이 있거나 나중에 재정의될 수 있다면 대신 defaults, 라우트 메타데이터 또는 런타임 메타데이터에 지정하세요.
렌더링된 태그 대신 확인된 메타데이터를 구조화된 데이터로 사용해야 하는 애플리케이션은 Head::toArray()를 호출할 수 있습니다. 반환되는 데이터에는 제목, Open Graph 값, JSON-LD 스키마 및 기타 확인된 메타데이터가 포함됩니다.