mirror of
https://github.com/MCKero6423/fuwari.git
synced 2026-10-02 03:15:35 +00:00
SEO 优化:补全 canonical、og:image、JSON-LD 及页面描述
Layout.astro:
- 新增 <link rel="canonical">,og:url / twitter:url 统一使用规范链接
- 新增 og:image / twitter:image:文章封面为绝对或 public URL 时使用封面,
否则回退站点 favicon-192 并将 twitter:card 从 summary_large_image
降级为 summary,避免声明大图卡片却无图
- banner 判断改用 typeof 收窄,兼容 404 页传入 banner={false} 的情况
posts/[...slug].astro (JSON-LD BlogPosting):
- 新增 dateModified(读取 frontmatter 的 updated 字段)
- 新增 image(仅绝对 URL 封面)和 mainEntityOfPage
- 移除遗留的 TODO 注释
页面 meta description:
- archive / friends / expenses / series 四个页面补充独立描述,
不再退化为用页面标题填充
astro.config.mjs:
- sitemap 增加 filter 排除 /archive/,与 robots.txt 的
Disallow: /archive/ 保持一致,消除收录信号矛盾
This commit is contained in:
1 parent
b35a071c6b
commit
6105577add
7 files changed
+42
-9
No files matched your search
+3
-1
@@ -102,7 +102,9 @@ export default defineConfig({
|
||||
}
|
||||
}),
|
||||
svelte(),
|
||||
sitemap(),
|
||||
sitemap({
|
||||
filter: (page) => !page.includes("/archive/"),
|
||||
}),
|
||||
],
|
||||
markdown: {
|
||||
remarkPlugins: [
|
||||
|
||||
@@ -30,6 +30,21 @@ interface Props {
|
||||
|
||||
let { title, banner, description, lang, setOGTypeArticle } = Astro.props;
|
||||
|
||||
// canonical URL
|
||||
const canonicalUrl = new URL(Astro.url.pathname, Astro.site).href;
|
||||
|
||||
// social share image: use the page's own image if it's an absolute or public URL,
|
||||
// otherwise fall back to the site favicon with a smaller "summary" card
|
||||
let ogImage: string | undefined;
|
||||
if (typeof banner === "string" && /^https?:\/\//.test(banner)) {
|
||||
ogImage = banner;
|
||||
} else if (typeof banner === "string" && banner.startsWith("/")) {
|
||||
ogImage = new URL(url(banner), Astro.site).href;
|
||||
}
|
||||
const twitterCard = ogImage ? "summary_large_image" : "summary";
|
||||
const ogImageUrl =
|
||||
ogImage ?? new URL(url("/favicon/favicon-light-192.png"), Astro.site).href;
|
||||
|
||||
// apply a class to the body element to decide the height of the banner, only used for initial page load
|
||||
// Swup can update the body for each page visit, but it's after the page transition, causing a delay for banner height change
|
||||
// so use Swup hooks instead to change the height immediately when a link is clicked
|
||||
@@ -83,21 +98,24 @@ const bannerOffset =
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="description" content={description || pageTitle}>
|
||||
<meta name="author" content={profileConfig.name}>
|
||||
<link rel="canonical" href={canonicalUrl}>
|
||||
|
||||
<meta property="og:site_name" content={siteConfig.title}>
|
||||
<meta property="og:url" content={Astro.url}>
|
||||
<meta property="og:url" content={canonicalUrl}>
|
||||
<meta property="og:title" content={pageTitle}>
|
||||
<meta property="og:description" content={description || pageTitle}>
|
||||
<meta property="og:image" content={ogImageUrl}>
|
||||
{setOGTypeArticle ? (
|
||||
<meta property="og:type" content="article" />
|
||||
) : (
|
||||
<meta property="og:type" content="website" />
|
||||
)}
|
||||
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta property="twitter:url" content={Astro.url}>
|
||||
<meta name="twitter:card" content={twitterCard}>
|
||||
<meta property="twitter:url" content={canonicalUrl}>
|
||||
<meta name="twitter:title" content={pageTitle}>
|
||||
<meta name="twitter:description" content={description || pageTitle}>
|
||||
<meta name="twitter:image" content={ogImageUrl}>
|
||||
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<meta name="generator" content={Astro.generator} />
|
||||
|
||||
@@ -3,12 +3,13 @@ import ArchivePanel from "@components/ArchivePanel.svelte";
|
||||
import I18nKey from "@i18n/i18nKey";
|
||||
import { i18n } from "@i18n/translation";
|
||||
import MainGridLayout from "@layouts/MainGridLayout.astro";
|
||||
import { siteConfig } from "@/config";
|
||||
import { getSortedPostsList } from "../utils/content-utils";
|
||||
|
||||
const sortedPostsList = await getSortedPostsList();
|
||||
---
|
||||
|
||||
<MainGridLayout title={i18n(I18nKey.archive)}>
|
||||
<MainGridLayout title={i18n(I18nKey.archive)} description={`${siteConfig.title}的全部文章归档,按时间浏览所有博客文章。`}>
|
||||
<ArchivePanel sortedPosts={sortedPostsList} client:only="svelte"></ArchivePanel>
|
||||
</MainGridLayout>
|
||||
|
||||
@@ -56,7 +56,7 @@ const historyData = [
|
||||
];
|
||||
---
|
||||
|
||||
<MainGridLayout title="运行成本">
|
||||
<MainGridLayout title="运行成本" description="本博客的运行成本明细,包括域名、CDN 等固定支出记录。">
|
||||
<div class="card-base p-6 md:p-8">
|
||||
|
||||
<div class="flex items-center gap-2 mb-6">
|
||||
|
||||
@@ -66,7 +66,7 @@ const friends = [
|
||||
];
|
||||
---
|
||||
|
||||
<MainGridLayout title="友链">
|
||||
<MainGridLayout title="友链" description="友情链接页面,收录了一些朋友的博客与网站。">
|
||||
<!-- 头部 -->
|
||||
<div class="flex items-center gap-4 mb-8 mt-4 px-2">
|
||||
<div class="avatar">
|
||||
|
||||
@@ -28,6 +28,11 @@ const { Content, headings } = await entry.render();
|
||||
|
||||
const { remarkPluginFrontmatter } = await entry.render();
|
||||
|
||||
const postUrl = new URL(getPostUrlBySlug(entry.slug), Astro.site).href;
|
||||
const coverImage = /^https?:\/\//.test(entry.data.image)
|
||||
? entry.data.image
|
||||
: undefined;
|
||||
|
||||
const jsonLd = {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "BlogPosting",
|
||||
@@ -40,10 +45,17 @@ const jsonLd = {
|
||||
url: Astro.site,
|
||||
},
|
||||
datePublished: formatDateToYYYYMMDD(entry.data.published),
|
||||
...(entry.data.updated && {
|
||||
dateModified: formatDateToYYYYMMDD(entry.data.updated),
|
||||
}),
|
||||
...(coverImage && { image: coverImage }),
|
||||
mainEntityOfPage: {
|
||||
"@type": "WebPage",
|
||||
"@id": postUrl,
|
||||
},
|
||||
inLanguage: entry.data.lang
|
||||
? entry.data.lang.replace("_", "-")
|
||||
: siteConfig.lang.replace("_", "-"),
|
||||
// TODO include cover image here
|
||||
};
|
||||
---
|
||||
<MainGridLayout banner={entry.data.image} title={entry.data.title} description={entry.data.description} lang={entry.data.lang} setOGTypeArticle={true} headings={headings} series={entry.data.series}>
|
||||
|
||||
@@ -5,6 +5,6 @@ import { i18n } from '@i18n/translation'
|
||||
import I18nKey from '@i18n/i18nKey'
|
||||
---
|
||||
|
||||
<MainGridLayout title={i18n(I18nKey.series)}>
|
||||
<MainGridLayout title={i18n(I18nKey.series)} description="按系列浏览博客文章,查看同一主题下的连载内容。">
|
||||
<SeriesPanel></SeriesPanel>
|
||||
</MainGridLayout>
|
||||
Reference in new issue
Block a user