diff --git a/.github/workflows/deploy.yaml b/.github/workflows/deploy.yaml index 7ca242b..698a9a1 100644 --- a/.github/workflows/deploy.yaml +++ b/.github/workflows/deploy.yaml @@ -43,7 +43,7 @@ jobs: - name: Build with VitePress run: | - pnpm run docs:build + VITE_HOSTNAME="https://keiyoushi.github.io" pnpm run docs:build touch website/.vitepress/dist/.nojekyll - name: Upload artifact diff --git a/website/.vitepress/config.ts b/website/.vitepress/config.ts index 1f3bdbf..7e5d680 100644 --- a/website/.vitepress/config.ts +++ b/website/.vitepress/config.ts @@ -1,4 +1,4 @@ -import { defineConfig } from 'vitepress'; +import { defineConfig, loadEnv } from 'vitepress' import { attrs } from '@mdit/plugin-attrs'; import { figure } from '@mdit/plugin-figure'; import { imgLazyload } from '@mdit/plugin-img-lazyload'; @@ -10,10 +10,13 @@ import shortcodePlugin from 'markdown-it-shortcode-tag'; import shortcodes from './config/shortcodes'; import ElementPlus from 'unplugin-element-plus/vite'; -import { GITHUB_EXTENSION_MIN_JSON } from './config/constants'; +import generateMeta from './config/hooks/generateMeta'; import nav from './config/navigation/nav'; import sidebar from './config/navigation/sidebar'; +const env = loadEnv('', process.cwd()); +const hostname: string = env.VITE_HOSTNAME || 'http://localhost:4173'; + // https://vitepress.dev/reference/site-config export default defineConfig({ title: "Keiyoushi", @@ -21,6 +24,7 @@ export default defineConfig({ cleanUrls: true, transformHead: (context) => { context.head.push(['meta', { name: 'robots', content: 'noindex, nofollow' }]); + generateMeta(context, hostname); }, themeConfig: { // https://vitepress.dev/reference/default-theme-config diff --git a/website/.vitepress/config/hooks/generateMeta.ts b/website/.vitepress/config/hooks/generateMeta.ts new file mode 100644 index 0000000..1be8c19 --- /dev/null +++ b/website/.vitepress/config/hooks/generateMeta.ts @@ -0,0 +1,133 @@ +import type { HeadConfig, TransformContext } from 'vitepress' + +function generateMeta(context: TransformContext, hostname: string) { + const head: HeadConfig[] = [] + const { pageData } = context + + const url = `${hostname}/${pageData.relativePath.replace(/((^|\/)index)?\.md$/, '$2')}` + + head.push(['link', { rel: 'canonical', href: url }]) + head.push(['meta', { property: 'og:url', content: url }]) + head.push(['meta', { name: 'twitter:url', content: url }]) + head.push(['meta', { name: 'twitter:card', content: 'summary_large_image' }]) + + if (pageData.frontmatter.theme) + head.push(['meta', { name: 'theme-color', content: pageData.frontmatter.theme }]) + + if (pageData.frontmatter.type) + head.push(['meta', { property: 'og:type', content: pageData.frontmatter.type }]) + + if (pageData.frontmatter.customMetaTitle) { + head.push([ + 'meta', + { + property: 'og:title', + content: pageData.frontmatter.customMetaTitle, + }, + ]) + head.push([ + 'meta', + { + name: 'twitter:title', + content: pageData.frontmatter.customMetaTitle, + }, + ]) + head.push(['meta', { property: 'og:site_name', content: '' }]) + } + else { + head.push(['meta', { property: 'og:title', content: pageData.frontmatter.title }]) + head.push(['meta', { name: 'twitter:title', content: pageData.frontmatter.title }]) + } + if (pageData.frontmatter.description) { + head.push([ + 'meta', + { + property: 'og:description', + content: pageData.frontmatter.description, + }, + ]) + head.push([ + 'meta', + { + name: 'twitter:description', + content: pageData.frontmatter.description, + }, + ]) + } + if (pageData.frontmatter.image) { + head.push([ + 'meta', + { + property: 'og:image', + content: `${hostname}/${pageData.frontmatter.image.replace(/^\//, '')}`, + }, + ]) + head.push([ + 'meta', + { + name: 'twitter:image', + content: `${hostname}/${pageData.frontmatter.image.replace(/^\//, '')}`, + }, + ]) + } + else { + const url = pageData.filePath.replace('index.md', '').replace('.md', '') + const imageUrl = `${url}/__og_image__/og.png`.replace(/\/\//g, '/').replace(/^\//, '') + + head.push(['meta', { property: 'og:image', content: `${hostname}/${imageUrl}` }]) + head.push(['meta', { property: 'og:image:width', content: '1200' }]) + head.push(['meta', { property: 'og:image:height', content: '628' }]) + head.push(['meta', { property: 'og:image:type', content: 'image/png' }]) + head.push(['meta', { property: 'og:image:alt', content: pageData.frontmatter.title }]) + head.push(['meta', { name: 'twitter:image', content: `${hostname}/${imageUrl}` }]) + head.push(['meta', { name: 'twitter:image:width', content: '1200' }]) + head.push(['meta', { name: 'twitter:image:height', content: '628' }]) + head.push(['meta', { name: 'twitter:image:alt', content: pageData.frontmatter.title }]) + } + if (pageData.frontmatter.tag) + head.push(['meta', { property: 'article:tag', content: pageData.frontmatter.tag }]) + + if (pageData.frontmatter.date) { + head.push([ + 'meta', + { + property: 'article:published_time', + content: pageData.frontmatter.date, + }, + ]) + } + if (pageData.lastUpdated && pageData.frontmatter.lastUpdated !== false) { + head.push([ + 'meta', + { + property: 'article:modified_time', + content: new Date(pageData.lastUpdated).toISOString(), + }, + ]) + } + + if (pageData.filePath === 'news/index.md') { + head.push([ + 'link', + { + rel: 'alternate', + type: 'application/rss+xml', + title: 'RSS feed for the news archive', + href: `${hostname}/feed.rss`, + }, + ]) + head.push([ + 'link', + { + rel: 'alternate', + type: 'application/json', + title: 'JSON of the news archive', + href: `${hostname}/news.json`, + }, + ]) + } + + return head +} + +export default generateMeta \ No newline at end of file