跳过主要内容
文档目录

元数据

学习如何为 MinuteShip 模板自定义元数据

本文档涵盖了 MinuteShip 模板中的元数据系统,以及如何自定义 SEO 设置。

核心功能

MinuteShip 模板内置了元数据系统,提供:

  • SEO 优化的页面标题和描述
  • 社交媒体分享元数据(Open Graph 和 Twitter)
  • 网站图标和应用图标 (Logo 和 Favicon)

理解元数据系统

MinuteShip 中的元数据通过几个关键文件进行配置:

1. 网站配置

主要网站配置在 src/config/website.ts 中定义:

src/config/website.ts

import { m } from '@/locale/paraglide/messages';

export const websiteConfig: WebsiteConfig = {
  metadata: {
    get name() { return m.site_name(); },
    get title() { return m.site_title(); },
    get description() { return m.site_description(); },
    images: {
      ogImage: '/og.png',
      logoLight: '/logo.png',
      logoDark: '/logo-dark.png',
    },
  },
  social: {
    github: 'https://github.com/your-org',
    discord: 'https://discord.gg/your-invite',
    twitter: 'https://x.com/your-handle',
    youtube: 'https://www.youtube.com/@your-handle',
  },
  // 其他配置部分...
};

此配置定义:

  • 网站的名称、标题和描述
  • Logo 和 Open Graph 图像路径
  • 社交平台的官方账号链接

2. 多语言消息

网站名称、标题与描述来自 project.inlang/messages/en.json 和 project.inlang/messages/zh.json:

project.inlang/messages/en.json

{
  "site_name": "Your App",
  "site_title": "Your App - Build your product",
  "site_description": "A description of your product"
}

在中文文件中维护同名 key。Paraglide 按当前请求语言解析消息;websiteConfig.metadata 使用 getter,避免在模块初始化时固定语言。默认英文 URL 不带前缀,中文使用 /zh,无需切换消息模块的 re-export。详见国际化。

3. SEO 辅助函数

src/lib/seo.ts 中的 seo(path, options) 返回页面的 meta、links 和 scripts:

  • 按当前语言生成 canonical URL,并为已本地化页面生成 hreflang 和 x-default。
  • 支持 canonicalLocale 与 alternateLocales,内容页可以仅列出实际存在的翻译。
  • 生成 Open Graph、Twitter、OG 语言与图片信息;Twitter 账号来自 websiteConfig.social.twitter。
  • canonical 和图片绝对地址以 VITE_BASE_URL 为基础,因此部署前应设置正确的站点地址。

新增完整翻译的静态页面时,同步更新 src/lib/locale.ts 的 LOCALIZED_PATHS 与站点地图逻辑。博客和法律页缺少翻译时重定向到实际版本,canonical 与语言链接不应指向不存在的内容。

4. 在路由中使用 SEO

每个路由通过 createFileRoute 中的 head() 函数定义其元数据:

src/routes/index.tsx

import { createFileRoute } from '@tanstack/react-router';
import { seo } from '@/lib/seo';

export const Route = createFileRoute('/')({
  head: () => ({
    ...seo('/', {
      title: 'MinuteShip - Home',
      description: 'Welcome to MinuteShip',
    }),
  }),
  component: HomePage,
});

5. 根布局元数据

根路由(src/routes/__root.tsx)定义全局元数据,包括字符集、视口、网站图标和默认的标题/描述:

src/routes/__root.tsx

export const Route = createRootRouteWithContext<{
  queryClient: QueryClient;
}>()({
  head: () => ({
    meta: [
      { charSet: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      { title: websiteConfig.metadata?.title },
      { name: 'description', content: websiteConfig.metadata?.description },
    ],
    links: [
      { rel: 'apple-touch-icon', sizes: '180x180', href: '/apple-touch-icon.png' },
      { rel: 'icon', type: 'image/png', sizes: '32x32', href: '/favicon-32x32.png' },
      { rel: 'icon', type: 'image/png', sizes: '16x16', href: '/favicon-16x16.png' },
      { rel: 'icon', href: '/favicon.ico' },
      { rel: 'manifest', href: '/manifest.json' },
    ],
  }),
  // ...
});

自定义网站元数据

基本网站信息

要更改基本网站信息(如名称、标题和描述),编辑当前使用的语言消息文件:

project.inlang/messages/en.json

{
  "site_name": "Your Website Name",
  "site_title": "Your Website Title - Tagline",
  "site_description": "A detailed description of your website"
}

自定义社交图像

要更改 Open Graph 图像和 Logo:

  1. 将您的图片放在 public 目录中
  2. 在 src/config/website.ts 中更新路径:

src/config/website.ts

metadata: {
  // 其他设置...
  images: {
    ogImage: '/your-og-image.png',  // 用于社交分享
    logoLight: '/your-logo-light.png',  // 明亮模式的 Logo
    logoDark: '/your-logo-dark.png',  // 暗黑模式的 Logo
  },
}

推荐尺寸:

  • OG 图像:1200×630 像素,在社交平台上获得更好的显示效果
  • Logo:至少 512×512 像素,适用于高分辨率显示

社交媒体链接

在网站配置中更新您的社交媒体官方账号链接:

src/config/website.ts

social: {
  github: 'https://github.com/YourUsername',
  twitter: 'https://x.com/YourHandle',
  discord: 'https://discord.gg/YourInvite',
  youtube: 'https://www.youtube.com/@YourChannel',
},

网站图标和应用图标 (Favicon)

要替换默认的网站图标和应用图标:

  1. 使用 Real Favicon Generator 等工具生成完整的图标集
  2. 将生成的文件放在 public 目录中
  3. 根路由已自动链接这些文件

页面特定元数据

在每个路由中,使用 seo() 辅助函数在 head() 中设置元数据:

export const Route = createFileRoute('/about')({
  head: () => ({
    ...seo('/about', {
      title: '关于我们',
      description: '了解更多关于我们团队的信息',
      image: '/images/about-og.png',
    }),
  }),
  component: AboutPage,
});

博客文章元数据

博客文章使用 frontmatter 元数据,会自动应用:

content/blog/example-post.md

---
title: 示例博客文章
description: 这是一个带有自定义元数据的示例博客文章
image: https://example.com/images/blog/example-post.png
date: "2024-01-01"
category: tutorial
---

内容在这里...

JSON-LD 结构化数据

seo() 现在返回 meta、links 和 scripts。公开页面通过 src/lib/structured-data.ts 生成包含 Organization、WebSite 与页面节点的 JSON-LD 图谱;关于、联系与博客列表分别使用 AboutPage、ContactPage 和 CollectionPage。认证与后台路径不会自动添加这套图谱。

博客详情追加 BlogPosting,博客列表追加 Blog。自定义 head() 的 scripts 时应保留 ...metadata.scripts,避免覆盖 seo() 生成的数据;用 jsonLdScript() 序列化额外节点,转义 <,防止内容提前结束脚本标签。请同步站点名称、社交链接、Logo 和 VITE_BASE_URL,确保结构化数据中的 URL 与本地化 canonical 一致。

最佳实践

  • 保持标题简洁:目标是标题少于 60 个字符,以在搜索结果中获得更好的显示
  • 描述性元描述:编写 150-160 个字符的引人注目的描述
  • 使用高质量图像:为 OG 和 Twitter 卡片创建专业、相关的图像
  • 包含关键词:在标题和描述中自然地包含相关关键词
  • 持续更新:保持元数据与您的内容更改同步
  • 移动优化:确保您的元数据在移动设备上看起来良好

下一步

现在您了解了如何在 MinuteShip 模板中自定义元数据,探索这些相关主题: