> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Laravel Head — document <head> 관리 패키지

> laravel/head 소개. Blade·Livewire·Inertia 전반에서 title, meta, Open Graph, canonical URL, robots, 성능 힌트, 구조화 데이터를 유창한 API로 관리하는 Laravel 공식 패키지. 2026년 7월 28일 릴리스.

## 시작하기

[laravel/head](https://github.com/laravel/head)는 애플리케이션의 문서 `<head>`를 유창한 API로 관리하는 Laravel 공식 패키지입니다. title·meta 태그, Open Graph, canonical URL, robots 디렉티브, 성능 힌트, 구조화 데이터를 지원하며, Blade·Livewire·Inertia 어느 것에서도 동작합니다. 2026년 7월 28일에 v0.1.0이 릴리스되었습니다.

```bash theme={null}
composer require laravel/head
```

## 해결 우선순위

페이지의 head 데이터는 우선도가 낮은 순으로 다음 5개 계층에서 해결됩니다.

1. 페이지 기본값
2. 라우트 그룹 메타데이터
3. 라우트 메타데이터
4. 런타임 메타데이터
5. 에러 페이지 메타데이터

상위 계층은 하위 계층을 필드 단위로 덮어씁니다. 예를 들어 런타임에서 설정한 title은 라우트의 title을 대체하지만, description까지는 대체하지 않습니다.

```mermaid theme={null}
graph TD
    A["페이지 기본값"] --> B["라우트 그룹<br>메타데이터"]
    B --> C["라우트 메타데이터"]
    C --> D["런타임 메타데이터"]
    D --> E["에러 페이지<br>메타데이터"]
    E --> F["최종적인<br>&lt;head&gt; 출력"]
```

## 기본값 등록

서비스 프로바이더에서 사이트 전체의 기본값을 등록합니다.

```php theme={null}
use Laravel\Head\Facades\Head;
use Laravel\Head\HeadBuilder;
use Laravel\Head\Enums\OgType;

Head::defaults(function (HeadBuilder $head) {
    $head
        ->title('Acme', suffix: ' - Acme')
        ->description('Build something great.')
        ->canonical()
        ->og(siteName: 'Acme', type: OgType::Website)
        ->searchableByRobots()
        ->preconnect('https://fonts.example.com');
});
```

기본값 계층은 가장 우선도가 낮은 페이지 계층입니다. 상위 계층에서 title이 설정되지 않는 한 `Acme`이 그대로 표시되며, 상위 계층이 title을 설정하면 상속된 suffix가 적용됩니다(`Head::title('About')`은 `About - Acme`이 됩니다).

## 라우트 메타데이터

정적 페이지는 라우트 정의에 직접 메타데이터를 연결할 수 있습니다.

```php theme={null}
Route::view('/contact', 'contact')
    ->name('contact')
    ->withHead(
        title: 'Contact Us',
        description: 'Get in touch.',
    );
```

그룹 전체에 공통 메타데이터를 적용할 수도 있습니다.

```php theme={null}
Route::withHead(robots: 'noindex, nofollow')
    ->prefix('admin')
    ->name('admin.')
    ->group(function () {
        Route::get('/dashboard', DashboardController::class)
            ->name('dashboard')
            ->withHead(title: 'Dashboard');
    });
```

`withHead()`는 Laravel 표준의 라우트 메타데이터 API(`->metadata()`의 `head` 키 아래)를 통해 순수한 배열을 저장하므로, 캐시된 라우트와의 호환성도 유지됩니다.

## 런타임 메타데이터

포스트 제목처럼 요청이 오기 전까지 알 수 없는 값은 `Head` 파사드로 실행 시 설정합니다.

```php theme={null}
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]);
}
```

조건부 메타데이터는 `when()` / `unless()`로 유창하게 작성할 수 있습니다.

```php theme={null}
Head::title($post->title)
    ->when($post->isDraft(), fn ($head) => $head->hiddenFromRobots());
```

## 에러 페이지

상태 코드별 메타데이터도 등록할 수 있습니다.

```php theme={null}
use Laravel\Head\ErrorPages;
use Laravel\Head\Facades\Head;

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.',
    );
});
```

등록된 에러 상태가 렌더링될 경우, 이 메타데이터는 다른 어떤 계층보다 우선됩니다.

## Open Graph와 Twitter Card

`og()`로 Open Graph 프로퍼티를 설정하고, `ogImage()` 등의 메서드로 이미지·비디오·오디오를 추가할 수 있습니다.

```php theme={null}
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,
    );
```

문서의 `title`과 `description`은 설정되지 않은 `og:title` / `og:description`을 자동으로 보완합니다.

Twitter Card는 기본값에 등록해 두는 것만으로 Open Graph와 같은 title·description·이미지에서 자동으로 렌더링됩니다.

```php theme={null}
use Laravel\Head\Enums\TwitterCard;
use Laravel\Head\Facades\Head;
use Laravel\Head\HeadBuilder;

Head::defaults(fn (HeadBuilder $head) => $head->twitter(
    card: TwitterCard::SummaryWithLargeImage,
));
```

개별 페이지에서 Twitter 값을 명시적으로 덮어쓸 수도 있습니다.

```php theme={null}
Head::twitter(title: $post->social_title)
    ->twitterImage($post->social_image_url, alt: $post->title);
```

## PWA·성능·아이콘

`pwa()` 헬퍼는 설치 가능한 웹 앱에 필요한 `<head>` 태그를 함께 설정합니다.

```php theme={null}
Head::pwa(
    name: 'Acme',
    manifest: '/site.webmanifest',
    themeColor: '#0f172a',
    appleTouchIcon: '/apple-touch-icon.png',
    appleWebAppStatusBarStyle: 'black',
);
```

## 테마 색상

테마 색상은 전역·라우트·런타임 어디에서든 설정할 수 있습니다. `Media` enum을 사용하면 미디어별 테마 색상도 지정할 수 있습니다.

```php theme={null}
use Laravel\Head\Enums\Media;

Head::themeColor('#ffffff', media: Media::Light)
    ->themeColor('#111827', media: Media::Dark);
```

`Media`에는 `Portrait`와 `Landscape`도 포함됩니다.

## 앱 메타데이터와 아이콘

Laravel Head에는 브라우저나 앱의 일반적인 메타데이터용 헬퍼가 포함되어 있습니다.

```php theme={null}
use Laravel\Head\Enums\ImageType;
use Laravel\Head\Enums\Media;

Head::applicationName('Acme')
    ->colorScheme('light dark')
    ->referrer('strict-origin-when-cross-origin')
    ->viewport('width=device-width, initial-scale=1')
    ->appleWebAppTitle('Acme')
    ->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` 인수를 받습니다.

## 성능과 발견 가능성

Laravel Head는 성능 힌트, 페이지네이션 링크, 로케일 대체 표현, 피드 발견용 태그도 렌더링할 수 있습니다.

```php theme={null}
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: 'Acme RSS')
    ->feed('/feed.atom', type: 'atom', title: 'Acme Atom');
```

`preloadAsset()` / `prefetchAsset()`은 `asset()` 헬퍼로 URL을 해결하고 확장자에서 `as` 속성을 자동 감지합니다.

```php theme={null}
Head::preloadAsset('fonts/inter.woff2')
    ->prefetchAsset('images/next.webp');
```

```html theme={null}
<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">
```

## 커스텀 태그

전용 메서드가 없는 태그는 `meta()` / `link()`로 추가할 수 있습니다.

```php theme={null}
Head::meta('format-detection', 'telephone=no')
    ->meta('article:author', $post->author->name)
    ->link('search', '/opensearch.xml', [
        'type' => 'application/opensearchdescription+xml',
        'title' => 'Acme Search',
    ]);
```

`meta()`는 일반 meta 태그에는 `name=`을 사용하지만, Open Graph(`og:`)나 기사 메타데이터(`article:`)처럼 본래 `property=`를 사용해야 하는 키의 경우에는 자동으로 전환됩니다.

```php theme={null}
Head::meta('description', 'About Acme')
    ->meta('og:title', 'About Acme');
```

```html theme={null}
<meta name="description" content="About Acme">
<meta property="og:title" content="About Acme">
```

## 구조화 데이터 (JSON-LD)

내장 스키마 빌더는 주요 JSON-LD 타입을 다룹니다.

```php theme={null}
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 타입도 표현할 수 있습니다.

브레드크럼 항목은 한 건씩 또는 한꺼번에 추가할 수 있습니다. 위치는 추가 순으로 자동 할당됩니다.

```php theme={null}
Head::schema(
    Schema::breadcrumbs()->items([
        'Home' => route('home'),
        'Shop' => route('shop.index'),
        'Shoes' => route('shop.category', 'shoes'),
    ])
);
```

FAQ의 질문도 비슷한 패턴입니다. `question()`으로 한 건씩, `questions()`로 한꺼번에 추가할 수 있습니다.

```php theme={null}
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.',
    ])
);
```

커스텀 스키마 타입은 명시적으로 등록할 수 있습니다.

```php theme={null}
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);
```

## 정리

`laravel/head`는 Blade·Livewire·Inertia 전반에서 SEO나 소셜 공유에 필요한 메타데이터를 한 곳에서 관리할 수 있는 패키지입니다. 기본값·라우트·런타임·에러 페이지의 5계층 구조에 의해, 사이트 전체의 일관성을 유지하면서 페이지 단위의 유연한 커스터마이징도 가능해집니다.

<Card title="laravel/head 리포지토리" icon="github" href="https://github.com/laravel/head">
  소스 코드와 최신 정보는 여기.
</Card>


## Related topics

- [패키지의 버전 호환성 관리](/ko/advanced/package-versioning.md)
- [패키지의 CHANGELOG와 릴리스 관리](/ko/advanced/package-changelog.md)
- [내 패키지](/ko/packages/index.md)
- [Laravel 패키지 개발](/ko/advanced/package-development.md)
- [Orchestra Testbench로 Laravel 패키지를 테스트하기](/ko/advanced/package-testing.md)
