> ## 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 — 文档 <head> 管理包

> 介绍 laravel/head。跨 Blade、Livewire、Inertia，以流畅的 API 管理 title、meta、Open Graph、canonical URL、robots、性能提示、结构化数据的 Laravel 官方包。2026 年 7 月 28 日发布。

## 前言

[laravel/head](https://github.com/laravel/head) 是一款以流畅的 API 管理应用文档 `<head>` 的 Laravel 官方包。支持 title、meta 标签、Open Graph、canonical URL、robots 指令、性能提示、结构化数据，可在 Blade、Livewire、Inertia 中运行。v0.1.0 于 2026 年 7 月 28 日发布。

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

document 的 `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()` 辅助方法会一起设置可安装 Web 应用所需的 `<head>` 标签。

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

## 主题色

主题色可以在全局、路由和运行时任一层级设置。使用 `Media` 枚举也可以按 media 区分指定不同的主题色。

```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 也可以渲染性能提示、分页链接、locale 备用表示以及供订阅发现的标签。

```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）

内置的 schema 构建器涵盖了主要的 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 对象，因此也可以表示自定义的 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.',
    ])
);
```

自定义 schema 类型可以显式注册。

```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 与社交分享所需元数据的包。通过默认值、路由、运行时、错误页面等多层结构，既能保持整个站点的一致性，也能对每个页面进行灵活的定制。

<Card title="laravel/head 仓库" icon="github" href="https://github.com/laravel/head">
  源代码与最新信息请见此处。
</Card>


## Related topics

- [包的 CHANGELOG 与发布管理](/zh-CN/advanced/package-changelog.md)
- [Laravel AI SDK](/zh-CN/ai-sdk.md)
- [包的版本兼容性管理](/zh-CN/advanced/package-versioning.md)
- [我的包](/zh-CN/packages/index.md)
- [Laravel Pennant 实战用例](/zh-CN/blog/laravel-pennant.md)
