Move seed.sql out of migrations and add SEO structured data
- Relocate seed.sql to scripts/ so wrangler d1 migrations apply doesn't treat it as a migration; update package.json, setup.mjs, README, and all AGENTS.md references. - Add src/lib/schema-org.ts builders (LocalBusiness, FAQPage, BlogPosting, BreadcrumbList) and emit JSON-LD via Base.astro. - Add lastmod to sitemap entries. - Set real site domain, worker route, and D1/KV ids. - Improve image loading hints and heading semantics across site components; switch BlogIndex to client:idle.
This commit is contained in:
+22
-2
@@ -8,6 +8,7 @@ interface Props {
|
||||
ogType?: "website" | "article";
|
||||
publishedTime?: Date | null;
|
||||
image?: string;
|
||||
jsonLd?: object | null | (object | null)[];
|
||||
}
|
||||
|
||||
const {
|
||||
@@ -17,6 +18,7 @@ const {
|
||||
ogType = "website",
|
||||
publishedTime = null,
|
||||
image,
|
||||
jsonLd = null,
|
||||
} = Astro.props;
|
||||
|
||||
const siteName = SITE_NAME;
|
||||
@@ -24,6 +26,11 @@ const origin = (Astro.site ?? Astro.url).toString().replace(/\/$/, "");
|
||||
const canonical = new URL(Astro.url.pathname, origin + "/").toString();
|
||||
const fullTitle = title.includes(siteName) ? title : `${title} — ${siteName}`;
|
||||
const ogImage = image ? (image.startsWith("http") ? image : new URL(image, origin + "/").toString()) : undefined;
|
||||
|
||||
const jsonLdItems = (Array.isArray(jsonLd) ? jsonLd : [jsonLd]).filter((item): item is object => item != null);
|
||||
const jsonLdHtml = jsonLdItems.length
|
||||
? JSON.stringify(jsonLdItems.length === 1 ? jsonLdItems[0] : jsonLdItems).replace(/</g, "\\u003c")
|
||||
: null;
|
||||
---
|
||||
|
||||
<!doctype html>
|
||||
@@ -38,16 +45,21 @@ const ogImage = image ? (image.startsWith("http") ? image : new URL(image, origi
|
||||
|
||||
<meta property="og:type" content={ogType} />
|
||||
<meta property="og:site_name" content={siteName} />
|
||||
<meta property="og:title" content={title} />
|
||||
<meta property="og:title" content={fullTitle} />
|
||||
<meta property="og:description" content={description} />
|
||||
<meta property="og:url" content={canonical} />
|
||||
<meta property="og:locale" content="zh_HK" />
|
||||
{ogImage && <meta property="og:image" content={ogImage} />}
|
||||
{ogImage && <meta property="og:image:alt" content={title} />}
|
||||
{publishedTime && <meta property="article:published_time" content={publishedTime.toISOString()} />}
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<meta name="twitter:title" content={title} />
|
||||
<meta name="twitter:title" content={fullTitle} />
|
||||
<meta name="twitter:description" content={description} />
|
||||
{ogImage && <meta name="twitter:image" content={ogImage} />}
|
||||
{ogImage && <meta name="twitter:image:alt" content={title} />}
|
||||
<meta name="theme-color" content="#FAF8F4" />
|
||||
|
||||
{jsonLdHtml && <script type="application/ld+json" is:inline set:html={jsonLdHtml} />}
|
||||
|
||||
<link rel="sitemap" href="/sitemap.xml" />
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
@@ -55,7 +67,15 @@ const ogImage = image ? (image.startsWith("http") ? image : new URL(image, origi
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Noto+Sans+HK:wght@400;500;700;900&family=Noto+Serif+HK:wght@600;700;900&display=swap"
|
||||
rel="stylesheet"
|
||||
media="print"
|
||||
onload="this.media='all'"
|
||||
/>
|
||||
<noscript>
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Noto+Sans+HK:wght@400;500;700;900&family=Noto+Serif+HK:wght@600;700;900&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
</noscript>
|
||||
</head>
|
||||
<body>
|
||||
<slot />
|
||||
|
||||
Reference in New Issue
Block a user