diff --git a/astro.config.mjs b/astro.config.mjs index 7f133c4..cb9c3ee 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -15,7 +15,7 @@ export default defineConfig({ site: "https://yukky-sandbox.dev/", vite: { optimizeDeps: { - exclude: ["fsevents"], + exclude: ["fsevents", "@cloudflare/pages-plugin-vercel-og"], }, }, output: "hybrid", diff --git a/bun.lockb b/bun.lockb index ce41e5a..4e8bc17 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/package.json b/package.json index d7c7f23..f8e0a69 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "@astrojs/react": "^3.6.2", "@astrojs/rss": "^4.0.7", "@astrojs/tailwind": "^5.1.0", + "@cloudflare/pages-plugin-vercel-og": "^0.1.2", "@formkit/tempo": "^0.1.2", "@types/react": "^18.3.5", "@types/react-dom": "^18.3.0", @@ -24,8 +25,6 @@ "microcms-js-sdk": "^3.0.0", "react": "^18.3.1", "react-dom": "^18.3.1", - "satori": "^0.11.0", - "sharp": "^0.33.5", "tailwindcss": "^3.3.3", "typescript-eslint": "^7.2.0" }, @@ -33,7 +32,6 @@ "@playwright/test": "^1.36.2", "@tailwindcss/typography": "^0.5.9", "@types/bun": "^1.0.8", - "@types/sharp": "^0.32.0", "eslint": "^8.46.0", "eslint-config-prettier": "^9.1.0", "eslint-config-standard-with-typescript": "^43.0.1", diff --git a/src/pages/og/_OgImage.tsx b/src/functions/post/_middleware.tsx similarity index 98% rename from src/pages/og/_OgImage.tsx rename to src/functions/post/_middleware.tsx index d4780c5..43e7e10 100644 --- a/src/pages/og/_OgImage.tsx +++ b/src/functions/post/_middleware.tsx @@ -1,11 +1,11 @@ -import satori from "satori"; -import sharp from "sharp"; +import React from "react"; +import vercelOGPagesPlugin from "@cloudflare/pages-plugin-vercel-og"; interface OgImageProps { - text: string; + ogTitle: string; } -const OgImage = ({ text }: OgImageProps): JSX.Element => { +const OgImage = ({ ogTitle }: OgImageProps): JSX.Element => { return (
{ paddingLeft: "48px", }} > -

{text}

+

{ogTitle}

{
); }; -export async function getOgImage(text: string): Promise { - const notoSansJpUrl = `https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@600`; - const reggeaeOneUlr = - "https://fonts.googleapis.com/css2?family=Reggae+One&display=swap&text=ゆっきーの砂場"; - const notoSansJpFontData = await getFontData(notoSansJpUrl); - const reggeaeOneFontData = await getFontData(reggeaeOneUlr); - const svg = await satori(, { - width: 800, - height: 400, - fonts: [ - { - name: "Noto Sans JP", - data: notoSansJpFontData, - style: "normal", - }, - { - name: "Reggae One", - data: reggeaeOneFontData, - style: "normal", - }, - ], - }); - - return await sharp(Buffer.from(svg)).png().toBuffer(); -} const getFontData = async (url: string): Promise => { const css = await ( @@ -128,3 +103,45 @@ const getFontData = async (url: string): Promise => { return await fetch(resource[1]).then(async (res) => await res.arrayBuffer()); }; + +export const onRequest = async () => { + const notoSansJpUrl = `https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@600`; + const reggeaeOneUlr = + "https://fonts.googleapis.com/css2?family=Reggae+One&display=swap&text=ゆっきーの砂場"; + const notoSansJpFontData = await getFontData(notoSansJpUrl); + const reggeaeOneFontData = await getFontData(reggeaeOneUlr); + return vercelOGPagesPlugin({ + imagePathSuffix: "/og-image.png", + component: ({ ogTitle }) => { + return ; + }, + extractors: { + on: { + 'meta[property="og:title"]': (props) => ({ + element(element) { + props.ogTitle = element.getAttribute("content"); + }, + }), + }, + }, + options: { + width: 800, + height: 400, + fonts: [ + { + name: "Noto Sans JP", + data: notoSansJpFontData, + style: "normal", + }, + { + name: "Reggae One", + data: reggeaeOneFontData, + style: "normal", + }, + ], + }, + autoInject: { + openGraph: true, + }, + }); +}; diff --git a/src/layouts/Layout.astro b/src/layouts/Layout.astro index eccce16..aac05f6 100644 --- a/src/layouts/Layout.astro +++ b/src/layouts/Layout.astro @@ -6,10 +6,9 @@ export interface Props { title: string; description: string; ogType?: string; - ogImageUrl?: string; } -const { title, description, ogType, ogImageUrl } = Astro.props; +const { title, description, ogType } = Astro.props; const canonicalURL = new URL(Astro.url.pathname, Astro.site); --- @@ -26,17 +25,13 @@ const canonicalURL = new URL(Astro.url.pathname, Astro.site); - { ogImageUrl !== undefined ? : '' } - { ogImageUrl !== undefined ? : '' } - { ogImageUrl !== undefined ? : '' } - { ogImageUrl !== undefined ? : } - { ogImageUrl !== undefined ? : '' } + diff --git a/src/layouts/PostLayout.astro b/src/layouts/PostLayout.astro index 1be27c3..9e8e3b3 100644 --- a/src/layouts/PostLayout.astro +++ b/src/layouts/PostLayout.astro @@ -5,14 +5,13 @@ export interface Props { title: string; description: string; createdAt: string; - slug: string; } -const { title, description, createdAt, slug } = Astro.props; +const { title, description, createdAt } = Astro.props; const OG_TYPE = "article"; const dateTypeCreatedAt = new Date(createdAt); --- - +
diff --git a/src/pages/og/[...slug].png.ts b/src/pages/og/[...slug].png.ts deleted file mode 100644 index 94a1a41..0000000 --- a/src/pages/og/[...slug].png.ts +++ /dev/null @@ -1,24 +0,0 @@ -import type { APIContext, APIRoute } from "astro"; -import { getEntry } from "astro:content"; -import { getOgImage } from "./_OgImage"; - -export const prerender = false; - -export async function GET({ params, redirect }: APIContext) { - const { slug } = params; - if (slug === undefined) { - return new Response(null, { - status: 500, - statusText: "No slug provided", - }); - } - const post = await getEntry("post", slug); - if (post === undefined) { - return new Response(null, { - status: 404, - statusText: "Not found", - }); - } - const body = await getOgImage(post?.data.title ?? "No title"); - return new Response(body); -} diff --git a/src/pages/post/[...slug].astro b/src/pages/post/[...slug].astro index 6b4dec5..9c7e817 100644 --- a/src/pages/post/[...slug].astro +++ b/src/pages/post/[...slug].astro @@ -10,7 +10,7 @@ export async function getStaticPaths() { const { entry } = Astro.props; const { Content } = await entry.render(); --- - +