依据 SECURITY_SEO_AUDIT.md 实施第一轮安全/SEO/GEO 修复
代码改动: - SEO-02 产品页标题品牌重复:Product::seoTitle() 去掉品牌后缀,由视图统一追加 $siteName - SEO-05/Geo-03 结构化数据:布局增 WebSite+SearchAction;产品页 Product+BreadcrumbList;文章页 Article+BreadcrumbList(含作者/发布日期) - SEO-06 hreflang 自引用(zh-CN/x-default) - SEC-02 新增 public/.well-known/security.txt - GEO-05 新增 public/llms.txt 记录文档(供未来开发者接手): - CHANGELOG.md:版本与变更日志 - docs/SECURITY_SEO_REMEDIATION.md:逐项状态总表 + 改动位置 + 上线 curl 自检清单 (SEC-01/REL-01~03/PHY-01~04 等需 Tailwind 构建或云端操作项标记为待办,未自动改以免破坏站点)
This commit is contained in:
@@ -48,6 +48,37 @@
|
||||
@endif
|
||||
</article>
|
||||
|
||||
@php
|
||||
// 结构化数据:Article + BreadcrumbList(审计 SEO-05 / GEO-03 作者与发布信号)
|
||||
$logoUrl = '/images/logo-dark.png';
|
||||
$articleSchema = [
|
||||
'@context' => 'https://schema.org',
|
||||
'@type' => 'Article',
|
||||
'headline' => $article->title,
|
||||
'description' => $article->seoDescription(),
|
||||
'author' => ['@type' => 'Organization', 'name' => $siteName],
|
||||
'publisher' => [
|
||||
'@type' => 'Organization',
|
||||
'name' => $siteName,
|
||||
'logo' => ['@type' => 'ImageObject', 'url' => asset($logoUrl)],
|
||||
],
|
||||
'datePublished' => $article->published_at?->toIso8601String(),
|
||||
'dateModified' => $article->updated_at?->toIso8601String(),
|
||||
'mainEntityOfPage' => ['@type' => 'WebPage', '@id' => url()->current()],
|
||||
];
|
||||
$breadcrumbSchema = [
|
||||
'@context' => 'https://schema.org',
|
||||
'@type' => 'BreadcrumbList',
|
||||
'itemListElement' => [
|
||||
['@type' => 'ListItem', 'position' => 1, 'name' => '首页', 'item' => url('/')],
|
||||
['@type' => 'ListItem', 'position' => 2, 'name' => '技术文章', 'item' => route('articles.index')],
|
||||
['@type' => 'ListItem', 'position' => 3, 'name' => $article->title, 'item' => url()->current()],
|
||||
],
|
||||
];
|
||||
@endphp
|
||||
<script type="application/ld+json">{!! json_encode($articleSchema, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_HEX_TAG) !!}</script>
|
||||
<script type="application/ld+json">{!! json_encode($breadcrumbSchema, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_HEX_TAG) !!}</script>
|
||||
|
||||
<div class="mt-6">
|
||||
<a href="{{ route('articles.index') }}" class="inline-flex items-center gap-1.5 text-sm font-medium text-primary hover:text-primary-hover">
|
||||
<x-icon name="arrow" :size="16" class="rotate-180" /> 返回文章列表
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
<title>@yield('title', $seoTitleDefault)</title>
|
||||
<meta name="description" content="@yield('description', $seoDescDefault)">
|
||||
<link rel="canonical" href="{{ url()->current() }}">
|
||||
<link rel="alternate" hreflang="zh-CN" href="{{ url()->current() }}">
|
||||
<link rel="alternate" hreflang="x-default" href="{{ url('/') }}">
|
||||
<meta property="og:type" content="website">
|
||||
<meta property="og:site_name" content="{{ $siteName }}">
|
||||
<meta property="og:title" content="@yield('title', $seoTitleDefault)">
|
||||
@@ -107,6 +109,22 @@
|
||||
"description": {!! json_encode($seoDescDefault, JSON_UNESCAPED_UNICODE) !!}
|
||||
}
|
||||
</script>
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@@context": "https://schema.org",
|
||||
"@@type": "WebSite",
|
||||
"name": {!! json_encode($siteName, JSON_UNESCAPED_UNICODE) !!},
|
||||
"url": {!! json_encode(url('/'), JSON_UNESCAPED_UNICODE) !!},
|
||||
"potentialAction": {
|
||||
"@@type": "SearchAction",
|
||||
"target": {
|
||||
"@@type": "EntryPoint",
|
||||
"urlTemplate": {!! json_encode(url('/search') . '?q={search_term_string}', JSON_UNESCAPED_UNICODE) !!}
|
||||
},
|
||||
"query-input": "required name=search_term_string"
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body class="font-sans text-fg bg-surface antialiased">
|
||||
|
||||
|
||||
@@ -35,6 +35,30 @@
|
||||
@endif
|
||||
</article>
|
||||
|
||||
@php
|
||||
// 结构化数据:Product + BreadcrumbList(审计 SEO-05)
|
||||
$productSchema = [
|
||||
'@context' => 'https://schema.org',
|
||||
'@type' => 'Product',
|
||||
'name' => $product->name,
|
||||
'description' => $product->seoDescription(),
|
||||
'brand' => ['@type' => 'Brand', 'name' => $siteName],
|
||||
'url' => url()->current(),
|
||||
'category' => $product->category?->name,
|
||||
];
|
||||
$breadcrumbSchema = [
|
||||
'@context' => 'https://schema.org',
|
||||
'@type' => 'BreadcrumbList',
|
||||
'itemListElement' => [
|
||||
['@type' => 'ListItem', 'position' => 1, 'name' => '首页', 'item' => url('/')],
|
||||
['@type' => 'ListItem', 'position' => 2, 'name' => '产品中心', 'item' => route('products.index')],
|
||||
['@type' => 'ListItem', 'position' => 3, 'name' => $product->name, 'item' => url()->current()],
|
||||
],
|
||||
];
|
||||
@endphp
|
||||
<script type="application/ld+json">{!! json_encode($productSchema, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_HEX_TAG) !!}</script>
|
||||
<script type="application/ld+json">{!! json_encode($breadcrumbSchema, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_HEX_TAG) !!}</script>
|
||||
|
||||
<div class="mt-6">
|
||||
<a href="{{ route('products.index') }}" class="inline-flex items-center gap-1.5 text-sm font-medium text-primary hover:text-primary-hover">
|
||||
<x-icon name="arrow" :size="16" class="rotate-180" /> 返回产品中心
|
||||
|
||||
Reference in New Issue
Block a user