feat: completed the production of open-graph-image for pages and articles using the astro-og-canvas library
This commit is contained in:
parent
388d2c2ba7
commit
18abe2f3d9
21 changed files with 138 additions and 99 deletions
|
|
@ -5,7 +5,7 @@ import { defineConfig } from "astro/config"
|
|||
|
||||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
site: "https://localhost:4321/",
|
||||
site: "https://astro-air.netlify.app",
|
||||
vite: {
|
||||
worker: {
|
||||
plugins: () => [],
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@
|
|||
"@types/react": "^18.3.12",
|
||||
"@types/react-dom": "^18.3.1",
|
||||
"astro": "^5.1.0",
|
||||
"astro-og-canvas": "^0.5.5",
|
||||
"canvaskit-wasm": "^0.39.1",
|
||||
"lucide-react": "^0.468.0",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
|
|
|
|||
31
pnpm-lock.yaml
generated
31
pnpm-lock.yaml
generated
|
|
@ -35,6 +35,12 @@ importers:
|
|||
astro:
|
||||
specifier: ^5.1.0
|
||||
version: 5.1.0(@types/node@22.10.2)(jiti@2.4.2)(rollup@4.27.4)(typescript@5.7.2)(yaml@2.6.1)
|
||||
astro-og-canvas:
|
||||
specifier: ^0.5.5
|
||||
version: 0.5.5(astro@5.1.0(@types/node@22.10.2)(jiti@2.4.2)(rollup@4.27.4)(typescript@5.7.2)(yaml@2.6.1))
|
||||
canvaskit-wasm:
|
||||
specifier: ^0.39.1
|
||||
version: 0.39.1
|
||||
lucide-react:
|
||||
specifier: ^0.468.0
|
||||
version: 0.468.0(react@18.3.1)
|
||||
|
|
@ -1151,6 +1157,9 @@ packages:
|
|||
'@vscode/l10n@0.0.18':
|
||||
resolution: {integrity: sha512-KYSIHVmslkaCDyw013pphY+d7x1qV8IZupYfeIfzNA+nsaWHbn5uPuQRvdRFsa9zFzGeudPuoGoZ1Op4jrJXIQ==}
|
||||
|
||||
'@webgpu/types@0.1.21':
|
||||
resolution: {integrity: sha512-pUrWq3V5PiSGFLeLxoGqReTZmiiXwY3jRkIG5sLLKjyqNxrwm/04b4nw7LSmGWJcKk59XOM/YRTUwOzo4MMlow==}
|
||||
|
||||
acorn-jsx@5.3.2:
|
||||
resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
|
||||
peerDependencies:
|
||||
|
|
@ -1248,6 +1257,12 @@ packages:
|
|||
resolution: {integrity: sha512-F6NW1RJo5pp2kPnnM97M5Ohw8zAGjv83MpxHqfAochH68n/kiXN57+hYaNUCA7XkScoVNr6yzvly3hsY34TGfQ==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
astro-og-canvas@0.5.5:
|
||||
resolution: {integrity: sha512-dbZ7voJAmvy8Zyv5zFsgENs9G4uhcCJ4nVuUPb7ymu8+Vp/jr/fdQDKPrLYUG2TSi/1HejYRnzkXcSv6ntlDTA==}
|
||||
engines: {node: '>=18.14.1'}
|
||||
peerDependencies:
|
||||
astro: ^3.0.0 || ^4.0.0 || ^5.0.0
|
||||
|
||||
astro@5.1.0:
|
||||
resolution: {integrity: sha512-g/cqwGK84Ozp5jyW45c3+2KQ4BeJtigbfwO8EA3lr7AC+XjE6/5dMvX4/bBaWf3gJVghd0L6cdqwlWikq+/Rrw==}
|
||||
engines: {node: ^18.17.1 || ^20.3.0 || >=22.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0'}
|
||||
|
|
@ -1329,6 +1344,9 @@ packages:
|
|||
caniuse-lite@1.0.30001684:
|
||||
resolution: {integrity: sha512-G1LRwLIQjBQoyq0ZJGqGIJUXzJ8irpbjHLpVRXDvBEScFJ9b17sgK6vlx0GAJFE21okD7zXl08rRRUfq6HdoEQ==}
|
||||
|
||||
canvaskit-wasm@0.39.1:
|
||||
resolution: {integrity: sha512-Gy3lCmhUdKq+8bvDrs9t8+qf7RvcjuQn+we7vTVVyqgOVO1UVfHpsnBxkTZw+R4ApEJ3D5fKySl9TU11hmjl/A==}
|
||||
|
||||
ccount@2.0.1:
|
||||
resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==}
|
||||
|
||||
|
|
@ -4743,6 +4761,8 @@ snapshots:
|
|||
|
||||
'@vscode/l10n@0.0.18': {}
|
||||
|
||||
'@webgpu/types@0.1.21': {}
|
||||
|
||||
acorn-jsx@5.3.2(acorn@8.14.0):
|
||||
dependencies:
|
||||
acorn: 8.14.0
|
||||
|
|
@ -4864,6 +4884,13 @@ snapshots:
|
|||
- supports-color
|
||||
- typescript
|
||||
|
||||
astro-og-canvas@0.5.5(astro@5.1.0(@types/node@22.10.2)(jiti@2.4.2)(rollup@4.27.4)(typescript@5.7.2)(yaml@2.6.1)):
|
||||
dependencies:
|
||||
astro: 5.1.0(@types/node@22.10.2)(jiti@2.4.2)(rollup@4.27.4)(typescript@5.7.2)(yaml@2.6.1)
|
||||
canvaskit-wasm: 0.39.1
|
||||
deterministic-object-hash: 2.0.2
|
||||
entities: 4.5.0
|
||||
|
||||
astro@5.1.0(@types/node@22.10.2)(jiti@2.4.2)(rollup@4.27.4)(typescript@5.7.2)(yaml@2.6.1):
|
||||
dependencies:
|
||||
'@astrojs/compiler': 2.10.3
|
||||
|
|
@ -5039,6 +5066,10 @@ snapshots:
|
|||
|
||||
caniuse-lite@1.0.30001684: {}
|
||||
|
||||
canvaskit-wasm@0.39.1:
|
||||
dependencies:
|
||||
'@webgpu/types': 0.1.21
|
||||
|
||||
ccount@2.0.1: {}
|
||||
|
||||
chalk@4.1.2:
|
||||
|
|
|
|||
BIN
public/avatar.png
Executable file
BIN
public/avatar.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 34 KiB |
|
|
@ -1,9 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 128 128">
|
||||
<path d="M50.4 78.5a75.1 75.1 0 0 0-28.5 6.9l24.2-65.7c.7-2 1.9-3.2 3.4-3.2h29c1.5 0 2.7 1.2 3.4 3.2l24.2 65.7s-11.6-7-28.5-7L67 45.5c-.4-1.7-1.6-2.8-2.9-2.8-1.3 0-2.5 1.1-2.9 2.7L50.4 78.5Zm-1.1 28.2Zm-4.2-20.2c-2 6.6-.6 15.8 4.2 20.2a17.5 17.5 0 0 1 .2-.7 5.5 5.5 0 0 1 5.7-4.5c2.8.1 4.3 1.5 4.7 4.7.2 1.1.2 2.3.2 3.5v.4c0 2.7.7 5.2 2.2 7.4a13 13 0 0 0 5.7 4.9v-.3l-.2-.3c-1.8-5.6-.5-9.5 4.4-12.8l1.5-1a73 73 0 0 0 3.2-2.2 16 16 0 0 0 6.8-11.4c.3-2 .1-4-.6-6l-.8.6-1.6 1a37 37 0 0 1-22.4 2.7c-5-.7-9.7-2-13.2-6.2Z" />
|
||||
<style>
|
||||
path { fill: #000; }
|
||||
@media (prefers-color-scheme: dark) {
|
||||
path { fill: #FFF; }
|
||||
}
|
||||
</style>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 749 B |
BIN
public/fonts/hwmc.otf
Normal file
BIN
public/fonts/hwmc.otf
Normal file
Binary file not shown.
|
|
@ -1,14 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" width="115" height="48">
|
||||
<path fill="#17191E"
|
||||
d="M7.77 36.35C6.4 35.11 6 32.51 6.57 30.62c.99 1.2 2.35 1.57 3.75 1.78 2.18.33 4.31.2 6.33-.78.23-.12.44-.27.7-.42.18.55.23 1.1.17 1.67a4.56 4.56 0 0 1-1.94 3.23c-.43.32-.9.61-1.34.91-1.38.94-1.76 2.03-1.24 3.62l.05.17a3.63 3.63 0 0 1-1.6-1.38 3.87 3.87 0 0 1-.63-2.1c0-.37 0-.74-.05-1.1-.13-.9-.55-1.3-1.33-1.32a1.56 1.56 0 0 0-1.63 1.26c0 .06-.03.12-.05.2Z" />
|
||||
<path fill="url(#a)"
|
||||
d="M7.77 36.35C6.4 35.11 6 32.51 6.57 30.62c.99 1.2 2.35 1.57 3.75 1.78 2.18.33 4.31.2 6.33-.78.23-.12.44-.27.7-.42.18.55.23 1.1.17 1.67a4.56 4.56 0 0 1-1.94 3.23c-.43.32-.9.61-1.34.91-1.38.94-1.76 2.03-1.24 3.62l.05.17a3.63 3.63 0 0 1-1.6-1.38 3.87 3.87 0 0 1-.63-2.1c0-.37 0-.74-.05-1.1-.13-.9-.55-1.3-1.33-1.32a1.56 1.56 0 0 0-1.63 1.26c0 .06-.03.12-.05.2Z" />
|
||||
<path fill="#17191E"
|
||||
d="M.02 30.31s4.02-1.95 8.05-1.95l3.04-9.4c.11-.45.44-.76.82-.76.37 0 .7.31.82.76l3.04 9.4c4.77 0 8.05 1.95 8.05 1.95L17 11.71c-.2-.56-.53-.91-.98-.91H7.83c-.44 0-.76.35-.97.9L.02 30.31Zm42.37-5.97c0 1.64-2.05 2.62-4.88 2.62-1.85 0-2.5-.45-2.5-1.41 0-1 .8-1.49 2.65-1.49 1.67 0 3.09.03 4.73.23v.05Zm.03-2.04a21.37 21.37 0 0 0-4.37-.36c-5.32 0-7.82 1.25-7.82 4.18 0 3.04 1.71 4.2 5.68 4.2 3.35 0 5.63-.84 6.46-2.92h.14c-.03.5-.05 1-.05 1.4 0 1.07.18 1.16 1.06 1.16h4.15a16.9 16.9 0 0 1-.36-4c0-1.67.06-2.93.06-4.62 0-3.45-2.07-5.64-8.56-5.64-2.8 0-5.9.48-8.26 1.19.22.93.54 2.83.7 4.06 2.04-.96 4.95-1.37 7.2-1.37 3.11 0 3.97.71 3.97 2.15v.57Zm11.37 3c-.56.07-1.33.07-2.12.07-.83 0-1.6-.03-2.12-.1l-.02.58c0 2.85 1.87 4.52 8.45 4.52 6.2 0 8.2-1.64 8.2-4.55 0-2.74-1.33-4.09-7.2-4.39-4.58-.2-4.99-.7-4.99-1.28 0-.66.59-1 3.65-1 3.18 0 4.03.43 4.03 1.35v.2a46.13 46.13 0 0 1 4.24.03l.02-.55c0-3.36-2.8-4.46-8.2-4.46-6.08 0-8.13 1.49-8.13 4.39 0 2.6 1.64 4.23 7.48 4.48 4.3.14 4.77.62 4.77 1.28 0 .7-.7 1.03-3.71 1.03-3.47 0-4.35-.48-4.35-1.47v-.13Zm19.82-12.05a17.5 17.5 0 0 1-6.24 3.48c.03.84.03 2.4.03 3.24l1.5.02c-.02 1.63-.04 3.6-.04 4.9 0 3.04 1.6 5.32 6.58 5.32 2.1 0 3.5-.23 5.23-.6a43.77 43.77 0 0 1-.46-4.13c-1.03.34-2.34.53-3.78.53-2 0-2.82-.55-2.82-2.13 0-1.37 0-2.65.03-3.84 2.57.02 5.13.07 6.64.11-.02-1.18.03-2.9.1-4.04-2.2.04-4.65.07-6.68.07l.07-2.93h-.16Zm13.46 6.04a767.33 767.33 0 0 1 .07-3.18H82.6c.07 1.96.07 3.98.07 6.92 0 2.95-.03 4.99-.07 6.93h5.18c-.09-1.37-.11-3.68-.11-5.65 0-3.1 1.26-4 4.12-4 1.33 0 2.28.16 3.1.46.03-1.16.26-3.43.4-4.43-.86-.25-1.81-.41-2.96-.41-2.46-.03-4.26.98-5.1 3.38l-.17-.02Zm22.55 3.65c0 2.5-1.8 3.66-4.64 3.66-2.81 0-4.61-1.1-4.61-3.66s1.82-3.52 4.61-3.52c2.82 0 4.64 1.03 4.64 3.52Zm4.71-.11c0-4.96-3.87-7.18-9.35-7.18-5.5 0-9.23 2.22-9.23 7.18 0 4.94 3.49 7.59 9.21 7.59 5.77 0 9.37-2.65 9.37-7.6Z" />
|
||||
<defs>
|
||||
<linearGradient id="a" x1="6.33" x2="19.43" y1="40.8" y2="34.6" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#D83333" />
|
||||
<stop offset="1" stop-color="#F041FF" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 2.9 KiB |
|
|
@ -1,14 +0,0 @@
|
|||
---
|
||||
import { en, zh } from "~/config"
|
||||
import { getLangFromUrl } from "~/i18n/utils"
|
||||
|
||||
const lang = getLangFromUrl(Astro.url)
|
||||
const config = lang === "zh" ? zh.meta : en.meta
|
||||
---
|
||||
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<link rel="icon" type="image/svg+xml" href={config.favicon} />
|
||||
<meta name="generator" content={Astro.generator} />
|
||||
<title>{config.title} - {config.slogan}</title>
|
||||
<meta name="description" content={config.description} />
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
import { getLangFromUrl, useTranslations } from "~/i18n/utils"
|
||||
import HomeLayout from "~/layouts/home.astro"
|
||||
import MainLayout from "~/layouts/main.astro"
|
||||
import { formatDate } from "~/utils"
|
||||
|
||||
interface Props {
|
||||
|
|
@ -16,7 +16,7 @@ const t = useTranslations(lang)
|
|||
const filteredPosts = posts.filter((post: any) => post.data.tags?.includes(tag))
|
||||
---
|
||||
|
||||
<HomeLayout>
|
||||
<MainLayout>
|
||||
<div class="mb-4 mt-2 text-2xl">
|
||||
{tag}
|
||||
</div>
|
||||
|
|
@ -43,4 +43,4 @@ const filteredPosts = posts.filter((post: any) => post.data.tags?.includes(tag))
|
|||
<p class="text-gray-500">{t("tag.no_posts")}</p>
|
||||
)
|
||||
}
|
||||
</HomeLayout>
|
||||
</MainLayout>
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ export const latestPosts = 8
|
|||
|
||||
const common = {
|
||||
meta: {
|
||||
favicon: "/favicon.svg",
|
||||
favicon: "/avatar.png",
|
||||
url: "https://blog.sunguoqi.com",
|
||||
},
|
||||
social: [
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ const postSchema = z.object({
|
|||
pubDate: z.coerce.date(),
|
||||
updatedDate: z.coerce.date().optional(),
|
||||
heroImage: z.string().optional(),
|
||||
ogImage: z.string().optional(),
|
||||
tags: z.array(z.string()).optional(),
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
title: "My First Blog Post"
|
||||
pubDate: 2020-07-01
|
||||
description: "This is the first post of my new Astro blog."
|
||||
ogImage: "https://sunguoqi.com/me.png"
|
||||
author: "Astro Learner"
|
||||
image:
|
||||
url: "https://docs.astro.build/assets/rose.webp"
|
||||
|
|
|
|||
|
|
@ -3,15 +3,51 @@ import "~/styles/globals.css"
|
|||
import { NoiseBackground } from "~/components/react/noise-background"
|
||||
import { ClientRouter } from "astro:transitions"
|
||||
import { getLangFromUrl } from "~/i18n/utils"
|
||||
import Head from "~/components/astro/head/root.astro"
|
||||
import { en, zh } from "~/config"
|
||||
|
||||
const lang = getLangFromUrl(Astro.url)
|
||||
|
||||
const { title, description, ogImage } = Astro.props
|
||||
|
||||
const ogImageURL = new URL(ogImage, Astro.site).href
|
||||
const permalink = new URL(Astro.url.pathname, Astro.site).href
|
||||
|
||||
const config = lang === "zh" ? zh.meta : en.meta
|
||||
---
|
||||
|
||||
<!doctype html>
|
||||
<html lang={lang}>
|
||||
<head>
|
||||
<Head />
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<link rel="icon" type="image/svg+xml" href={config.favicon} />
|
||||
<title>
|
||||
{
|
||||
!title
|
||||
? `${config.title} - ${config.slogan}`
|
||||
: `${config.title} - ${title}`
|
||||
}
|
||||
</title>
|
||||
<meta name="generator" content={Astro.generator} />
|
||||
<meta
|
||||
name="description"
|
||||
content={!description ? config.description : description}
|
||||
/>
|
||||
|
||||
<!-- Open Graph / Facebook -->
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:url" content={permalink} />
|
||||
<meta property="og:title" content={title} />
|
||||
<meta property="og:description" content={description} />
|
||||
<meta property="og:image" content={ogImageURL} />
|
||||
|
||||
<!-- Twitter -->
|
||||
<meta property="twitter:card" content="summary_large_image" />
|
||||
<meta property="twitter:url" content={permalink} />
|
||||
<meta property="twitter:title" content={title} />
|
||||
<meta property="twitter:description" content={description} />
|
||||
<meta property="twitter:image" content={ogImageURL} />
|
||||
|
||||
<ClientRouter />
|
||||
<script is:inline>
|
||||
const setTheme = () => {
|
||||
|
|
|
|||
|
|
@ -2,9 +2,13 @@
|
|||
import Header from "~/components/astro/header.astro"
|
||||
import Navigation from "~/components/astro/nav.astro"
|
||||
import BaseLayout from "~/layouts/base.astro"
|
||||
|
||||
const { title, description, ogImage } = Astro.props
|
||||
const filename = Astro.url.pathname.split("/").filter(Boolean).pop() ?? ""
|
||||
const openGraphImage = !ogImage ? `/og/${filename}.png` : ogImage
|
||||
---
|
||||
|
||||
<BaseLayout>
|
||||
<BaseLayout title={title} description={description} ogImage={openGraphImage}>
|
||||
<main class="max-auto mb-10 w-full max-w-3xl">
|
||||
<Header />
|
||||
<Navigation />
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
---
|
||||
import HomeLayout from "~/layouts/home.astro"
|
||||
import "~/styles/post.css"
|
||||
import { formatDate } from "~/utils"
|
||||
|
||||
const { title, description, pubDate, updatedDate } = Astro.props
|
||||
---
|
||||
|
||||
<HomeLayout>
|
||||
<head slot="head">
|
||||
<title>{title}</title>
|
||||
{description && <meta name="description" content={description} />}
|
||||
</head>
|
||||
{
|
||||
title && (
|
||||
<div class="mb-4 flex flex-col gap-3">
|
||||
<h1 class="text-2xl font-bold">{title}</h1>
|
||||
{pubDate && (
|
||||
<p class="text-sm text-gray-500 dark:text-gray-400">
|
||||
{formatDate(pubDate)}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
<article class="prose dark:prose-invert">
|
||||
<slot />
|
||||
</article>
|
||||
{
|
||||
updatedDate && (
|
||||
<div class="mt-10">
|
||||
<p class="text-sm text-gray-500 dark:text-gray-400">
|
||||
更新时间:{formatDate(updatedDate)}
|
||||
</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</HomeLayout>
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
import AboutContentEn from "~/config/en/about.mdx"
|
||||
import AboutContentZh from "~/config/zh/about.mdx"
|
||||
import { getLangFromUrl } from "~/i18n/utils"
|
||||
import HomeLayout from "~/layouts/home.astro"
|
||||
import MainLayout from "~/layouts/main.astro"
|
||||
import { getLanguagePaths } from "~/utils/langs"
|
||||
|
||||
export function getStaticPaths() {
|
||||
|
|
@ -11,10 +11,12 @@ export function getStaticPaths() {
|
|||
|
||||
const lang = getLangFromUrl(Astro.url)
|
||||
const AboutContent = lang === "zh" ? AboutContentZh : AboutContentEn
|
||||
|
||||
const ogImage = "https://sunguoqi.com/me.png"
|
||||
---
|
||||
|
||||
<HomeLayout>
|
||||
<MainLayout title="about" description="test" ogImage={ogImage}>
|
||||
<div class="prose dark:prose-invert">
|
||||
<AboutContent />
|
||||
</div>
|
||||
</HomeLayout>
|
||||
</MainLayout>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
import { getLangFromUrl } from "~/i18n/utils"
|
||||
import HomeLayout from "~/layouts/home.astro"
|
||||
import MainLayout from "~/layouts/main.astro"
|
||||
import { formatDate, getPostsByLocale } from "~/utils"
|
||||
import { getLanguagePaths } from "~/utils/langs"
|
||||
|
||||
|
|
@ -27,7 +27,7 @@ const postsByYear = posts.reduce(
|
|||
const years = Object.keys(postsByYear).sort((a, b) => Number(b) - Number(a))
|
||||
---
|
||||
|
||||
<HomeLayout>
|
||||
<MainLayout>
|
||||
<div class="space-y-8">
|
||||
{
|
||||
years.map((year) => (
|
||||
|
|
@ -49,4 +49,4 @@ const years = Object.keys(postsByYear).sort((a, b) => Number(b) - Number(a))
|
|||
))
|
||||
}
|
||||
</div>
|
||||
</HomeLayout>
|
||||
</MainLayout>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
import Blog from "~/components/astro/blog.astro"
|
||||
import Footer from "~/components/astro/footer.astro"
|
||||
import Intro from "~/components/astro/intro.astro"
|
||||
import HomeLayout from "~/layouts/home.astro"
|
||||
import MainLayout from "~/layouts/main.astro"
|
||||
import { getLanguagePaths } from "~/utils/langs"
|
||||
|
||||
export function getStaticPaths() {
|
||||
|
|
@ -10,8 +10,8 @@ export function getStaticPaths() {
|
|||
}
|
||||
---
|
||||
|
||||
<HomeLayout>
|
||||
<MainLayout>
|
||||
<Intro />
|
||||
<Blog />
|
||||
<Footer />
|
||||
</HomeLayout>
|
||||
</MainLayout>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
---
|
||||
import { langs } from "~/i18n/ui"
|
||||
import PostLayout from "~/layouts/post.astro"
|
||||
import MainLayout from "~/layouts/main.astro"
|
||||
import "~/styles/post.css"
|
||||
import { getPostsByLocale } from "~/utils"
|
||||
|
||||
export async function getStaticPaths() {
|
||||
|
|
@ -21,6 +22,8 @@ export async function getStaticPaths() {
|
|||
const { post } = Astro.props
|
||||
---
|
||||
|
||||
<PostLayout {...post.data}>
|
||||
<MainLayout {...post.data}>
|
||||
<article class="prose dark:prose-invert">
|
||||
<div set:html={post.rendered.html} />
|
||||
</PostLayout>
|
||||
</article>
|
||||
</MainLayout>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
import { getLangFromUrl } from "~/i18n/utils"
|
||||
import HomeLayout from "~/layouts/home.astro"
|
||||
import MainLayout from "~/layouts/main.astro"
|
||||
import { getPostsByLocale } from "~/utils"
|
||||
import { getLanguagePaths } from "~/utils/langs"
|
||||
|
||||
|
|
@ -13,7 +13,7 @@ const posts = await getPostsByLocale(lang)
|
|||
const tags = [...new Set(posts.map((post: any) => post.data.tags).flat())]
|
||||
---
|
||||
|
||||
<HomeLayout>
|
||||
<MainLayout>
|
||||
<div>
|
||||
{
|
||||
tags.map((tag) => (
|
||||
|
|
@ -23,4 +23,4 @@ const tags = [...new Set(posts.map((post: any) => post.data.tags).flat())]
|
|||
))
|
||||
}
|
||||
</div>
|
||||
</HomeLayout>
|
||||
</MainLayout>
|
||||
|
|
|
|||
34
src/pages/og/[...route].ts
Normal file
34
src/pages/og/[...route].ts
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
import { OGImageRoute } from "astro-og-canvas"
|
||||
import { defaultLanguage } from "~/config"
|
||||
import { getPostsByLocale } from "~/utils"
|
||||
|
||||
const posts = await getPostsByLocale(defaultLanguage)
|
||||
|
||||
// Transform the collection into an object
|
||||
// @ts-ignore
|
||||
const pages = Object.fromEntries(posts.map(({ id, data }) => [id, { data }]))
|
||||
|
||||
export const { getStaticPaths, GET } = OGImageRoute({
|
||||
// The name of your dynamic route segment.
|
||||
// In this case it’s `route`, because the file is named `[...route].ts`.
|
||||
param: "route",
|
||||
|
||||
// A collection of pages to generate images for.
|
||||
pages,
|
||||
// For each page, this callback will be used to customize the OG image.
|
||||
getImageOptions: async (_, { data }: (typeof pages)[string]) => {
|
||||
return {
|
||||
title: data.title,
|
||||
description: data.description,
|
||||
bgGradient: [
|
||||
[6, 38, 45],
|
||||
[8, 3, 2],
|
||||
],
|
||||
logo: {
|
||||
path: "./public/avatar.png",
|
||||
size: [100],
|
||||
},
|
||||
fonts: ["./public/fonts/hwmc.otf"],
|
||||
}
|
||||
},
|
||||
})
|
||||
Loading…
Add table
Reference in a new issue