ycs77/inertia-laravel-ssr-head

Inertia Laravel 的简单 SSR 头

v2.0.0 2024-08-15 13:54 UTC

README

Latest Version on Packagist Software License GitHub Tests Action Status Style CI Build Status Total Downloads

英语 | 繁体中文

Inertia Laravel 的简单 SSR 头

  • 😎 解决了 Inertia.js x Laravel 应用中 Open Graph Meta 的爬虫问题
  • ❌ 不需要 Headless Chrome、Node.js 或 PHP V8 扩展
  • ✨ 自动更新 Inertia 页面标题

受 Inertia.js 文档中根模板数据的启发。

NOT 完整的 SSR 解决方案!它不能解决 SEO 问题!

因为我制作了这个包,以便更容易让机器人爬取 Inertia.js 应用中的 Open Graph Meta,无需安装(或无法安装)Headless Chrome、Node.js 或 PHP V8 扩展。这适用于您不熟悉如何在服务器上安装上述包,或服务器不支持它们(例如共享主机)的情况。

如果您需要完整的 SSR 解决方案,请使用Inertia.js 官方服务器端渲染

支持的版本

安装

通过 composer 安装包

composer require ycs77/inertia-laravel-ssr-head

<title> 替换为 @inertiaHead 指令

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1">
-   <title>{{ config('app.name') }}</title>
+   @inertiaHead
</head>

<body>
    @inertia
</body>
</html>

安装客户端插件

然后安装客户端 npm 包

npm install inertia-title
// or
yarn add inertia-title

该包仅自动更新客户端 <title> 标签。

resources/js/app.js 中添加 Vue 2 插件

...
+import InertiaTitle from 'inertia-title/vue2'

+Vue.use(InertiaTitle)

createInertiaApp({
  ...
})

在 Vue 3 中使用 resources/js/app.js

...
+import InertiaTitle from 'inertia-title/vue3'

createInertiaApp({
  ...
  setup({ el, App, props, plugin }) {
    createApp({ render: () => h(App, props) })
      .use(plugin)
+     .use(InertiaTitle)
      .mount(el)
  },
})

在 React 或其他客户端框架中使用

...
+import { inertiaTitle } from 'inertia-title'

+inertiaTitle()

配置

使用以下命令发布配置文件

php artisan vendor:publish --tag="inertia-ssr-head-config"

您可以在配置 inertia-ssr-head.php 中设置 Twitter 网站用户名或多个

<?php

return [

    'fb_app_id' => env('FB_APP_ID'),

    'twitter_site' => env('TWITTER_SITE'),
    'twitter_site_id' => env('TWITTER_SITE_ID'),

    'twitter_creator' => env('TWITTER_CREATOR'),
    'twitter_creator_id' => env('TWITTER_CREATOR_ID'),

    'twitter_app_name' => env('TWITTER_APP_NAME', env('APP_NAME')),

    'twitter_app_ios_id' => env('TWITTER_APP_IOS_ID'),
    'twitter_app_ios_url' => env('TWITTER_APP_IOS_URL'),

    'twitter_app_googleplay_id' => env('TWITTER_APP_GOOGLEPLAY_ID'),
    'twitter_app_googleplay_url' => env('TWITTER_APP_GOOGLEPLAY_URL'),

];

使用方法

设置页面标题和描述

return Inertia::render('Home')
    ->title('My homepage')
    ->description('Hello, This is my homepage~');

然后将被渲染到以下 HTML 标签中

<head>
    <title>My homepage</title>
    <meta name="description" content="Hello, This is my homepage~">
</head>

首次访问页面时,head 标签仅在服务器端渲染,客户端只更新 <title>,不更新其他元标签。因为此包的目的是仅允许机器人爬取元标签,所以在客户端省略。

标题将被注入到属性中,您可以使用 Vue Options API 中的 title$page.props.title 获取页面标题

export default {
  props: {
    title: String,
  },
  created() {
    this.title             // => 'My homepage'  (with props)
    this.$page.props.title // => 'My homepage'  (with $page)
  },
}

或使用 Vue Composition API

<script setup>
import { usePage } from '@inertiajs/vue3'

const props = defineProps({
  title: String,
})

const page = usePage()

props.title      // => 'My homepage'  (with props)
page.props.title // => 'My homepage'  (with page.props)
</script>

此外,如果您使用此包,则不要使用 Inertia <Head>

标题模板

如果您想在标题后添加网站名称,请在 AppServiceProvider 中使用 titleTemplate(),支持使用字符串和闭包

use Inertia\Inertia;

class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
        Inertia::titleTemplate(fn ($title) => $title ? "$title - My App" : 'My App');
        // or pass string and %s will be replaced with the page title
        Inertia::titleTemplate('%s - My App');
    }
}

或为单个 Inertia 页面设置

return Inertia::render('Home')
    ->title('My homepage', '%s :: My App');

如果您只想禁用单个页面的标题模板,可以在 title() 中设置 false

return Inertia::render('Home')
    ->title('My homepage', false);

Open Graph 元标签

渲染 Open Graph 标签,有 titledescriptionogMeta()ogMeta() 将生成 Open Graph 元标签 og:titleog:descriptionog:image

return Inertia::render('Home')
    ->title('My homepage')
    ->description('Hello, This is my homepage~')
    ->image('https://example.com/image')
    ->ogMeta();

// Same...
return Inertia::render('Home')
    ->title('My homepage')
    ->description('Hello, This is my homepage~')
    ->image('https://example.com/image')
    ->ogTitle('My homepage')
    ->ogDescription('Hello, This is my homepage~')
    ->ogImage('https://example.com/image');

或如果您只想渲染 og:titleog:description 元标签

return Inertia::render('Home')
    ->title('My homepage')
    ->ogTitle('Custom og title')
    ->ogDescription('Custom og description...');

Twitter Card 元标签

使用 twitterSummaryCard() 添加 Twitter Summary card 元标签

return Inertia::render('Home')
    ->title('My homepage')
    ->description('Hello, This is my homepage~')
    ->image('https://example.com/image')
    ->twitterSummaryCard();

使用 twitterLargeCard() 添加 Summary large image card 元标签

return Inertia::render('Home')
    ->title('My homepage')
    ->description('Hello, This is my homepage~')
    ->image('https://example.com/image')
    ->twitterLargeCard()
    ->twitterCreator('@creator_twitter_name');

使用 twitterAppCard() 添加 App card 元标签

return Inertia::render('AppHome')
    ->title('App title')
    ->description('App description...')
    ->twitterAppCard()
    ->twitterAppForIphone([
        'name' => 'Your APP',
        'id' => '123456789',
        'url' => 'https://example.com/iphone_app',
    ])
    ->twitterAppForIpad([
        'name' => 'Your APP',
        'id' => '123456789',
        'url' => 'https://example.com/ipad_app',
    ])
    ->twitterAppForGoogleplay([
        'name' => 'Your APP',
        'id' => '123456789',
        'url' => 'https://example.com/googleplay_app',
    ]);

使用 twitterPlayerCard() 添加 Player card 元标签

return Inertia::render('Home')
    ->title('Video title')
    ->description('Video description...')
    ->image('https://example.com/video_thumbnail')
    ->twitterPlayerCard([
        'url' => 'https://example.com/video',
        'width' => 640,
        'height' => 360,
    ]);

自定义 head 标签

使用 tag() 方法将在 <head> 中添加自定义 HTML 标签

return Inertia::render('Home')
    ->title('My homepage')
    ->tag('<meta name="my-meta" content="some data...">')
    ->tag('<meta name="my-meta" content="%s">', e('some data...')) // escape data

测试

composer test

参考

贡献

请参阅CONTRIBUTING以获取详细信息。

安全漏洞

请审查我们的安全策略了解如何报告安全漏洞。

鸣谢

许可

MIT 许可证(MIT)。请参阅许可文件以获取更多信息。