diff --git a/.vitepress/hooks/index.ts b/.vitepress/hooks/index.ts
index 029a1996e..b2bfa321c 100644
--- a/.vitepress/hooks/index.ts
+++ b/.vitepress/hooks/index.ts
@@ -2,7 +2,7 @@
* Barrel generated using @taskylizard/tasker.
*/
-export * from "./meta";
-export * from "./opengraph";
-export * from "./rss";
-export * from "./satoriConfig";
+export * from './meta'
+export * from './opengraph'
+export * from './rss'
+export * from './satoriConfig'
diff --git a/.vitepress/hooks/meta.ts b/.vitepress/hooks/meta.ts
index 7b00fe5d5..c2f59ecd8 100644
--- a/.vitepress/hooks/meta.ts
+++ b/.vitepress/hooks/meta.ts
@@ -1,89 +1,100 @@
-import type { HeadConfig, TransformContext } from "vitepress";
+import type { HeadConfig, TransformContext } from 'vitepress'
export function generateMeta(context: TransformContext, hostname: string) {
- const head: HeadConfig[] = [];
- const { pageData } = context;
+ const head: HeadConfig[] = []
+ const { pageData } = context
- const url = `${hostname}/${pageData.relativePath.replace(/((^|\/)index)?\.md$/, "$2")}`;
+ const url = `${hostname}/${pageData.relativePath.replace(/((^|\/)index)?\.md$/, '$2')}`
head.push(
- ["link", { rel: "canonical", href: url }],
- ["meta", { property: "og:url", content: url }],
- ["meta", { name: "twitter:url", content: url }],
- ["meta", { name: "twitter:card", content: "summary_large_image" }],
- ["meta", { property: "og:title", content: pageData.frontmatter.title }],
- ["meta", { name: "twitter:title", content: pageData.frontmatter.title }],
- );
+ ['link', { rel: 'canonical', href: url }],
+ ['meta', { property: 'og:url', content: url }],
+ ['meta', { name: 'twitter:url', content: url }],
+ ['meta', { name: 'twitter:card', content: 'summary_large_image' }],
+ ['meta', { property: 'og:title', content: pageData.frontmatter.title }],
+ ['meta', { name: 'twitter:title', content: pageData.frontmatter.title }]
+ )
if (pageData.frontmatter.description) {
head.push(
[
- "meta",
+ 'meta',
{
- property: "og:description",
- content: pageData.frontmatter.description,
- },
+ property: 'og:description',
+ content: pageData.frontmatter.description
+ }
],
[
- "meta",
+ 'meta',
{
- name: "twitter:description",
- content: pageData.frontmatter.description,
- },
- ],
- );
+ name: 'twitter:description',
+ content: pageData.frontmatter.description
+ }
+ ]
+ )
}
if (pageData.frontmatter.image) {
head.push([
- "meta",
+ 'meta',
{
- property: "og:image",
- content: `${hostname}/${pageData.frontmatter.image.replace(/^\//, "")}`,
- },
- ]);
+ property: 'og:image',
+ content: `${hostname}/${pageData.frontmatter.image.replace(/^\//, '')}`
+ }
+ ])
head.push([
- "meta",
+ 'meta',
{
- name: "twitter:image",
- content: `${hostname}/${pageData.frontmatter.image.replace(/^\//, "")}`,
- },
- ]);
+ 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`.replaceAll("//", "/").replace(/^\//, "");
+ const url = pageData.filePath.replace('index.md', '').replace('.md', '')
+ const imageUrl = `${url}/__og_image__/og.png`
+ .replaceAll('//', '/')
+ .replace(/^\//, '')
head.push(
- ["meta", { property: "og:image", content: `${hostname}/${imageUrl}` }],
- ["meta", { property: "og:image:width", content: "1200" }],
- ["meta", { property: "og:image:height", content: "628" }],
- ["meta", { property: "og:image:type", content: "image/png" }],
- ["meta", { property: "og:image:alt", content: pageData.frontmatter.title }],
- ["meta", { name: "twitter:image", content: `${hostname}/${imageUrl}` }],
- ["meta", { name: "twitter:image:width", content: "1200" }],
- ["meta", { name: "twitter:image:height", content: "628" }],
- ["meta", { name: "twitter:image:alt", content: pageData.frontmatter.title }],
- );
+ ['meta', { property: 'og:image', content: `${hostname}/${imageUrl}` }],
+ ['meta', { property: 'og:image:width', content: '1200' }],
+ ['meta', { property: 'og:image:height', content: '628' }],
+ ['meta', { property: 'og:image:type', content: 'image/png' }],
+ [
+ 'meta',
+ { property: 'og:image:alt', content: pageData.frontmatter.title }
+ ],
+ ['meta', { name: 'twitter:image', content: `${hostname}/${imageUrl}` }],
+ ['meta', { name: 'twitter:image:width', content: '1200' }],
+ ['meta', { name: 'twitter:image:height', content: '628' }],
+ [
+ 'meta',
+ { name: 'twitter:image:alt', content: pageData.frontmatter.title }
+ ]
+ )
}
if (pageData.frontmatter.tag) {
- head.push(["meta", { property: "article:tag", content: pageData.frontmatter.tag }]);
+ head.push([
+ 'meta',
+ { property: 'article:tag', content: pageData.frontmatter.tag }
+ ])
}
if (pageData.frontmatter.date) {
head.push([
- "meta",
+ 'meta',
{
- property: "article:published_time",
- content: pageData.frontmatter.date,
- },
- ]);
+ property: 'article:published_time',
+ content: pageData.frontmatter.date
+ }
+ ])
}
if (pageData.lastUpdated && pageData.frontmatter.lastUpdated !== false) {
head.push([
- "meta",
+ 'meta',
{
- property: "article:modified_time",
- content: new Date(pageData.lastUpdated).toISOString(),
- },
- ]);
+ property: 'article:modified_time',
+ content: new Date(pageData.lastUpdated).toISOString()
+ }
+ ])
}
- return head;
+ return head
}
diff --git a/.vitepress/hooks/opengraph.ts b/.vitepress/hooks/opengraph.ts
index e6424a6dd..28a20ecbd 100644
--- a/.vitepress/hooks/opengraph.ts
+++ b/.vitepress/hooks/opengraph.ts
@@ -1,71 +1,71 @@
-import { mkdir, readFile, writeFile } from "node:fs/promises";
-import { dirname, resolve } from "node:path";
-import { fileURLToPath } from "node:url";
-import { createContentLoader } from "vitepress";
-import type { ContentData, SiteConfig } from "vitepress";
-import { type SatoriOptions, satoriVue } from "x-satori/vue";
-import { renderAsync } from "@resvg/resvg-js";
-import consola from "consola";
+import { mkdir, readFile, writeFile } from 'node:fs/promises'
+import { dirname, resolve } from 'node:path'
+import { fileURLToPath } from 'node:url'
+import { createContentLoader } from 'vitepress'
+import type { ContentData, SiteConfig } from 'vitepress'
+import { type SatoriOptions, satoriVue } from 'x-satori/vue'
+import { renderAsync } from '@resvg/resvg-js'
+import consola from 'consola'
-const __dirname = dirname(fileURLToPath(import.meta.url));
-const __fonts = resolve(__dirname, "../fonts");
+const __dirname = dirname(fileURLToPath(import.meta.url))
+const __fonts = resolve(__dirname, '../fonts')
export async function generateImages(config: SiteConfig): Promise
{
- const pages = await createContentLoader("**/*.md", { excerpt: true }).load();
- const template = await readFile(resolve(__dirname, "./Template.vue"), "utf-8");
+ const pages = await createContentLoader('**/*.md', { excerpt: true }).load()
+ const template = await readFile(resolve(__dirname, './Template.vue'), 'utf-8')
- const fonts: SatoriOptions["fonts"] = [
+ const fonts: SatoriOptions['fonts'] = [
{
- name: "Inter",
- data: await readFile(resolve(__fonts, "Inter-Regular.otf")),
+ name: 'Inter',
+ data: await readFile(resolve(__fonts, 'Inter-Regular.otf')),
weight: 400,
- style: "normal",
+ style: 'normal'
},
{
- name: "Inter",
- data: await readFile(resolve(__fonts, "Inter-Medium.otf")),
+ name: 'Inter',
+ data: await readFile(resolve(__fonts, 'Inter-Medium.otf')),
weight: 500,
- style: "normal",
+ style: 'normal'
},
{
- name: "Inter",
- data: await readFile(resolve(__fonts, "Inter-SemiBold.otf")),
+ name: 'Inter',
+ data: await readFile(resolve(__fonts, 'Inter-SemiBold.otf')),
weight: 600,
- style: "normal",
+ style: 'normal'
},
{
- name: "Inter",
- data: await readFile(resolve(__fonts, "Inter-Bold.otf")),
+ name: 'Inter',
+ data: await readFile(resolve(__fonts, 'Inter-Bold.otf')),
weight: 700,
- style: "normal",
- },
- ];
+ style: 'normal'
+ }
+ ]
for (const page of pages) {
await generateImage({
page,
template,
outDir: config.outDir,
- fonts,
- });
+ fonts
+ })
}
- return consola.info("Generated opengraph images.");
+ return consola.info('Generated opengraph images.')
}
interface GenerateImagesOptions {
- page: ContentData;
- template: string;
- outDir: string;
- fonts: SatoriOptions["fonts"];
+ page: ContentData
+ template: string
+ outDir: string
+ fonts: SatoriOptions['fonts']
}
async function generateImage({
page,
template,
outDir,
- fonts,
+ fonts
}: GenerateImagesOptions): Promise {
- const { frontmatter, url } = page;
+ const { frontmatter, url } = page
const options: SatoriOptions = {
width: 1200,
@@ -73,24 +73,24 @@ async function generateImage({
fonts,
props: {
title:
- frontmatter.layout === "home"
+ frontmatter.layout === 'home'
? frontmatter.hero.name ?? frontmatter.title
: frontmatter.title,
description:
- frontmatter.layout === "home"
+ frontmatter.layout === 'home'
? frontmatter.hero.tagline ?? frontmatter.description
- : frontmatter.description,
- },
- };
+ : frontmatter.description
+ }
+ }
- const svg = await satoriVue(options, template);
+ const svg = await satoriVue(options, template)
- const render = await renderAsync(svg);
+ const render = await renderAsync(svg)
- const outputFolder = resolve(outDir, url.slice(1), "__og_image__");
- const outputFile = resolve(outputFolder, "og.png");
+ const outputFolder = resolve(outDir, url.slice(1), '__og_image__')
+ const outputFile = resolve(outputFolder, 'og.png')
- await mkdir(outputFolder, { recursive: true });
+ await mkdir(outputFolder, { recursive: true })
- await writeFile(outputFile, render.asPng());
+ await writeFile(outputFile, render.asPng())
}
diff --git a/.vitepress/hooks/rss.ts b/.vitepress/hooks/rss.ts
index 671b943c1..ad98b006d 100644
--- a/.vitepress/hooks/rss.ts
+++ b/.vitepress/hooks/rss.ts
@@ -1,9 +1,13 @@
-import path from "node:path";
-import { writeFileSync } from "node:fs";
-import { Feed } from "feed";
-import { createContentLoader, type ContentData, type SiteConfig } from "vitepress";
-import consola from "consola";
-import { meta } from "../constants";
+import path from 'node:path'
+import { writeFileSync } from 'node:fs'
+import { Feed } from 'feed'
+import {
+ createContentLoader,
+ type ContentData,
+ type SiteConfig
+} from 'vitepress'
+import consola from 'consola'
+import { meta } from '../constants'
export async function generateFeed(config: SiteConfig): Promise {
const feed: Feed = new Feed({
@@ -11,32 +15,35 @@ export async function generateFeed(config: SiteConfig): Promise {
link: meta.hostname,
title: `FMHY blog`,
description: meta.description,
- language: "en-US",
- image: "https://github.com/fmhy.png",
+ language: 'en-US',
+ image: 'https://github.com/fmhy.png',
favicon: `${meta.hostname}/favicon.ico`,
- copyright: `Copyright (c) 2023-present FMHY`,
- });
+ copyright: `Copyright (c) 2023-present FMHY`
+ })
- const posts: ContentData[] = await createContentLoader("posts/*.md", {
+ const posts: ContentData[] = await createContentLoader('posts/*.md', {
excerpt: true,
render: true,
transform: (rawData) => {
return rawData.sort((a, b) => {
- return Number(new Date(b.frontmatter.date)) - Number(new Date(a.frontmatter.date));
- });
- },
- }).load();
+ return (
+ Number(new Date(b.frontmatter.date)) -
+ Number(new Date(a.frontmatter.date))
+ )
+ })
+ }
+ }).load()
for (const { url, frontmatter, html } of posts) {
feed.addItem({
title: frontmatter.title as string,
- id: `${meta.hostname}${url.replace(/\/\d+\./, "/")}`,
- link: `${meta.hostname}${url.replace(/\/\d+\./, "/")}`,
+ id: `${meta.hostname}${url.replace(/\/\d+\./, '/')}`,
+ link: `${meta.hostname}${url.replace(/\/\d+\./, '/')}`,
date: frontmatter.date,
- content: html!,
- });
+ content: html!
+ })
}
- writeFileSync(path.join(config.outDir, "feed.rss"), feed.rss2());
- return consola.info("Generated rss feed.");
+ writeFileSync(path.join(config.outDir, 'feed.rss'), feed.rss2())
+ return consola.info('Generated rss feed.')
}
diff --git a/.vitepress/hooks/satoriConfig.ts b/.vitepress/hooks/satoriConfig.ts
index e106e8c7d..30a380180 100644
--- a/.vitepress/hooks/satoriConfig.ts
+++ b/.vitepress/hooks/satoriConfig.ts
@@ -1,47 +1,47 @@
-import { readFile } from "node:fs/promises";
-import { dirname, resolve } from "node:path";
-import { fileURLToPath } from "node:url";
-import type { SatoriOptions } from "x-satori/vue";
-import { defineSatoriConfig } from "x-satori/vue";
+import { readFile } from 'node:fs/promises'
+import { dirname, resolve } from 'node:path'
+import { fileURLToPath } from 'node:url'
+import type { SatoriOptions } from 'x-satori/vue'
+import { defineSatoriConfig } from 'x-satori/vue'
-const __dirname = dirname(fileURLToPath(import.meta.url));
-const __fonts = resolve(__dirname, "../fonts");
+const __dirname = dirname(fileURLToPath(import.meta.url))
+const __fonts = resolve(__dirname, '../fonts')
-const fonts: SatoriOptions["fonts"] = [
+const fonts: SatoriOptions['fonts'] = [
{
- name: "Inter",
- data: await readFile(resolve(__fonts, "Inter-Regular.otf")),
+ name: 'Inter',
+ data: await readFile(resolve(__fonts, 'Inter-Regular.otf')),
weight: 400,
- style: "normal",
+ style: 'normal'
},
{
- name: "Inter",
- data: await readFile(resolve(__fonts, "Inter-Medium.otf")),
+ name: 'Inter',
+ data: await readFile(resolve(__fonts, 'Inter-Medium.otf')),
weight: 500,
- style: "normal",
+ style: 'normal'
},
{
- name: "Inter",
- data: await readFile(resolve(__fonts, "Inter-SemiBold.otf")),
+ name: 'Inter',
+ data: await readFile(resolve(__fonts, 'Inter-SemiBold.otf')),
weight: 600,
- style: "normal",
+ style: 'normal'
},
{
- name: "Inter",
- data: await readFile(resolve(__fonts, "Inter-Bold.otf")),
+ name: 'Inter',
+ data: await readFile(resolve(__fonts, 'Inter-Bold.otf')),
weight: 700,
- style: "normal",
- },
-];
+ style: 'normal'
+ }
+]
export default defineSatoriConfig({
width: 1200,
height: 628,
fonts,
props: {
- title: "Title",
+ title: 'Title',
description:
- "Lorem ipsum dolor sit amet, qui minim labore adipisicing minim sint cillum sint consectetur cupidatat.",
- dir: "/j",
- },
-});
+ 'Lorem ipsum dolor sit amet, qui minim labore adipisicing minim sint cillum sint consectetur cupidatat.',
+ dir: '/j'
+ }
+})
diff --git a/.vitepress/markdown/base64.ts b/.vitepress/markdown/base64.ts
index f85b59b02..e7106c7c4 100644
--- a/.vitepress/markdown/base64.ts
+++ b/.vitepress/markdown/base64.ts
@@ -1,25 +1,29 @@
-import { type MarkdownRenderer } from "vitepress";
+import { type MarkdownRenderer } from 'vitepress'
// FIXME: tasky: possibly write less horror jank?
export function base64DecodePlugin(md: MarkdownRenderer) {
- const decode = (str: string): string => Buffer.from(str, "base64").toString("binary");
+ const decode = (str: string): string =>
+ Buffer.from(str, 'base64').toString('binary')
// Save the original rule for backticks
const defaultRender =
md.renderer.rules.code_inline ||
function (tokens, idx, options, env, self) {
- return self.renderToken(tokens, idx, options);
- };
+ return self.renderToken(tokens, idx, options)
+ }
md.renderer.rules.code_inline = function (tokens, idx, options, env, self) {
// @ts-expect-error shut the fuck up already I HATE THIS
- if (!env.frontmatter.title || (env.frontmatter.title && !env.frontmatter.title === "base64")) {
- return defaultRender(tokens, idx, options, env, self);
+ if (
+ !env.frontmatter.title ||
+ (env.frontmatter.title && !env.frontmatter.title === 'base64')
+ ) {
+ return defaultRender(tokens, idx, options, env, self)
}
- const token = tokens[idx];
- const content = token.content;
+ const token = tokens[idx]
+ const content = token.content
return `${content}
`;
- };
+ content
+ )}').then(() => { const originalText = codeEl.textContent; codeEl.textContent = 'Copied'; setTimeout(() => codeEl.textContent = originalText, 3000); }).catch(console.error); })(this)">${content}
`
+ }
}
diff --git a/.vitepress/markdown/emoji.ts b/.vitepress/markdown/emoji.ts
index b1009b1b4..86c2cc696 100644
--- a/.vitepress/markdown/emoji.ts
+++ b/.vitepress/markdown/emoji.ts
@@ -1,42 +1,42 @@
-import { icons as twemoji } from "@iconify-json/twemoji";
-import type { MarkdownRenderer } from "vitepress";
+import { icons as twemoji } from '@iconify-json/twemoji'
+import type { MarkdownRenderer } from 'vitepress'
export const defs = {
...Object.fromEntries(
Object.entries(twemoji.icons).map(([key]) => {
- return [key, ""];
- }),
- ),
-};
+ return [key, '']
+ })
+ )
+}
export function emojiRender(md: MarkdownRenderer) {
md.renderer.rules.emoji = (tokens, idx) => {
- if (tokens[idx].markup.startsWith("star")) {
- return ` `;
+ if (tokens[idx].markup.startsWith('star')) {
+ return ` `
}
- return ` `;
- };
+ return ` `
+ }
}
export function movePlugin(
plugins: { name: string }[],
pluginAName: string,
- order: "before" | "after",
- pluginBName: string,
+ order: 'before' | 'after',
+ pluginBName: string
) {
- const pluginBIndex = plugins.findIndex((p) => p.name === pluginBName);
- if (pluginBIndex === -1) return;
+ const pluginBIndex = plugins.findIndex((p) => p.name === pluginBName)
+ if (pluginBIndex === -1) return
- const pluginAIndex = plugins.findIndex((p) => p.name === pluginAName);
- if (pluginAIndex === -1) return;
+ const pluginAIndex = plugins.findIndex((p) => p.name === pluginAName)
+ if (pluginAIndex === -1) return
- if (order === "before" && pluginAIndex > pluginBIndex) {
- const pluginA = plugins.splice(pluginAIndex, 1)[0];
- plugins.splice(pluginBIndex, 0, pluginA);
+ if (order === 'before' && pluginAIndex > pluginBIndex) {
+ const pluginA = plugins.splice(pluginAIndex, 1)[0]
+ plugins.splice(pluginBIndex, 0, pluginA)
}
- if (order === "after" && pluginAIndex < pluginBIndex) {
- const pluginA = plugins.splice(pluginAIndex, 1)[0];
- plugins.splice(pluginBIndex, 0, pluginA);
+ if (order === 'after' && pluginAIndex < pluginBIndex) {
+ const pluginA = plugins.splice(pluginAIndex, 1)[0]
+ plugins.splice(pluginBIndex, 0, pluginA)
}
}
diff --git a/.vitepress/markdown/toggleStarred.ts b/.vitepress/markdown/toggleStarred.ts
index 1ec258d39..bef8e1655 100644
--- a/.vitepress/markdown/toggleStarred.ts
+++ b/.vitepress/markdown/toggleStarred.ts
@@ -1,18 +1,18 @@
-import type { MarkdownRenderer } from "vitepress";
+import type { MarkdownRenderer } from 'vitepress'
-const excluded = ["Beginners Guide"];
+const excluded = ['Beginners Guide']
export function toggleStarredPlugin(md: MarkdownRenderer) {
md.renderer.rules.list_item_open = (tokens, index, options, env, self) => {
- const contentToken = tokens[index + 2];
+ const contentToken = tokens[index + 2]
if (
!excluded.includes(env.frontmatter.title) &&
contentToken &&
- contentToken.content.startsWith(":star:")
+ contentToken.content.startsWith(':star:')
) {
- return ``;
+ return ` `
} else {
- return self.renderToken(tokens, index, options);
+ return self.renderToken(tokens, index, options)
}
- };
+ }
}
diff --git a/.vitepress/middleware/cors.ts b/.vitepress/middleware/cors.ts
index 6e74e76e9..ff667ab18 100644
--- a/.vitepress/middleware/cors.ts
+++ b/.vitepress/middleware/cors.ts
@@ -1,6 +1,6 @@
-import { corsEventHandler } from "nitro-cors";
+import { corsEventHandler } from 'nitro-cors'
export default corsEventHandler((_event) => {}, {
- origin: "*",
- methods: "*",
-});
+ origin: '*',
+ methods: '*'
+})
diff --git a/.vitepress/routes/index.post.ts b/.vitepress/routes/index.post.ts
index fef287925..b7f3cc785 100644
--- a/.vitepress/routes/index.post.ts
+++ b/.vitepress/routes/index.post.ts
@@ -1,28 +1,32 @@
-import { fetcher } from "itty-fetcher";
-import { FeedbackSchema, getFeedbackOption } from "../types/Feedback";
+import { fetcher } from 'itty-fetcher'
+import { FeedbackSchema, getFeedbackOption } from '../types/Feedback'
export default defineEventHandler(async (event) => {
- const { message, page, type } = await readValidatedBody(event, FeedbackSchema.parseAsync);
- const env = useRuntimeConfig(event);
+ const { message, page, type } = await readValidatedBody(
+ event,
+ FeedbackSchema.parseAsync
+ )
+ const env = useRuntimeConfig(event)
- let description = `${message}\n\n`;
- if (page) description += `**Page:** \`${page}\``;
+ let description = `${message}\n\n`
+ if (page) description += `**Page:** \`${page}\``
await fetcher()
.post(env.WEBHOOK_URL, {
- username: "Feedback",
- avatar_url: "https://i.kym-cdn.com/entries/icons/facebook/000/043/403/cover3.jpg",
+ username: 'Feedback',
+ avatar_url:
+ 'https://i.kym-cdn.com/entries/icons/facebook/000/043/403/cover3.jpg',
embeds: [
{
color: 3447003,
title: getFeedbackOption(type).label,
- description,
- },
- ],
+ description
+ }
+ ]
})
.catch((error) => {
- throw new Error(error);
- });
+ throw new Error(error)
+ })
- return { status: "ok" };
-});
+ return { status: 'ok' }
+})
diff --git a/.vitepress/routes/test.ts b/.vitepress/routes/test.ts
index a6fcdc197..cb36c7c7a 100644
--- a/.vitepress/routes/test.ts
+++ b/.vitepress/routes/test.ts
@@ -1,3 +1,3 @@
export default eventHandler(() => {
- return { nitro: "works" };
-});
+ return { nitro: 'works' }
+})
diff --git a/.vitepress/theme/Layout.vue b/.vitepress/theme/Layout.vue
index e855ff916..ada010bfb 100644
--- a/.vitepress/theme/Layout.vue
+++ b/.vitepress/theme/Layout.vue
@@ -1,47 +1,47 @@
diff --git a/.vitepress/theme/PostLayout.vue b/.vitepress/theme/PostLayout.vue
index f48b27970..2a307c726 100644
--- a/.vitepress/theme/PostLayout.vue
+++ b/.vitepress/theme/PostLayout.vue
@@ -1,20 +1,20 @@
@@ -22,6 +22,8 @@ const { frontmatter } = useData();
{{ frontmatter.title }}
- {{ frontmatter.description }} • {{ formatDate(frontmatter.date) }}
+
+ {{ frontmatter.description }} • {{ formatDate(frontmatter.date) }}
+
diff --git a/.vitepress/theme/Posts.vue b/.vitepress/theme/Posts.vue
index 626903b6e..dfbe4be0d 100644
--- a/.vitepress/theme/Posts.vue
+++ b/.vitepress/theme/Posts.vue
@@ -1,14 +1,14 @@
@@ -28,11 +28,14 @@ const formatDate = (raw: string): string => {
- {{ post.title }} -
+ {{ post.title }}
+ -
Published on
- {{ formatDate(post.date) }}
+
+ {{ formatDate(post.date) }}
+
diff --git a/.vitepress/theme/components/Announcement.vue b/.vitepress/theme/components/Announcement.vue
index bbea99494..df3282db4 100644
--- a/.vitepress/theme/components/Announcement.vue
+++ b/.vitepress/theme/components/Announcement.vue
@@ -1,7 +1,7 @@
@@ -9,7 +9,8 @@ const { frontmatter } = useData();
v-if="frontmatter.hero.prelink"
:href="frontmatter.hero.prelink.link"
target="_blank"
- class="inline-flex items-center rounded-lg bg-[var(--vp-c-default-soft)] px-4 py-1 text-sm font-semibold mb-3">
+ class="inline-flex items-center rounded-lg bg-[var(--vp-c-default-soft)] px-4 py-1 text-sm font-semibold mb-3"
+ >
{{ frontmatter.hero.prelink.title }}
diff --git a/.vitepress/theme/components/Authors.vue b/.vitepress/theme/components/Authors.vue
index 1ad0a8959..36f7dd1f8 100644
--- a/.vitepress/theme/components/Authors.vue
+++ b/.vitepress/theme/components/Authors.vue
@@ -1,39 +1,41 @@
@@ -41,7 +43,7 @@ const authors = computed(() => data.filter((author) => props.authors.includes(au
diff --git a/.vitepress/theme/components/CardField.vue b/.vitepress/theme/components/CardField.vue
index ae5511400..eb836d5f7 100644
--- a/.vitepress/theme/components/CardField.vue
+++ b/.vitepress/theme/components/CardField.vue
@@ -1,7 +1,7 @@