diff --git a/.astro/astro/content.d.ts b/.astro/astro/content.d.ts deleted file mode 100644 index ef995ed..0000000 --- a/.astro/astro/content.d.ts +++ /dev/null @@ -1,221 +0,0 @@ -declare module 'astro:content' { - interface Render { - '.mdx': Promise<{ - Content: import('astro').MarkdownInstance<{}>['Content']; - headings: import('astro').MarkdownHeading[]; - remarkPluginFrontmatter: Record; - }>; - } -} - -declare module 'astro:content' { - interface RenderResult { - Content: import('astro/runtime/server/index.js').AstroComponentFactory; - headings: import('astro').MarkdownHeading[]; - remarkPluginFrontmatter: Record; - } - interface Render { - '.md': Promise; - } - - export interface RenderedContent { - html: string; - metadata?: { - imagePaths: Array; - [key: string]: unknown; - }; - } -} - -declare module 'astro:content' { - type Flatten = T extends { [K: string]: infer U } ? U : never; - - export type CollectionKey = keyof AnyEntryMap; - export type CollectionEntry = Flatten; - - export type ContentCollectionKey = keyof ContentEntryMap; - export type DataCollectionKey = keyof DataEntryMap; - - type AllValuesOf = T extends any ? T[keyof T] : never; - type ValidContentEntrySlug = AllValuesOf< - ContentEntryMap[C] - >['slug']; - - /** @deprecated Use `getEntry` instead. */ - export function getEntryBySlug< - C extends keyof ContentEntryMap, - E extends ValidContentEntrySlug | (string & {}), - >( - collection: C, - // Note that this has to accept a regular string too, for SSR - entrySlug: E, - ): E extends ValidContentEntrySlug - ? Promise> - : Promise | undefined>; - - /** @deprecated Use `getEntry` instead. */ - export function getDataEntryById( - collection: C, - entryId: E, - ): Promise>; - - export function getCollection>( - collection: C, - filter?: (entry: CollectionEntry) => entry is E, - ): Promise; - export function getCollection( - collection: C, - filter?: (entry: CollectionEntry) => unknown, - ): Promise[]>; - - export function getEntry< - C extends keyof ContentEntryMap, - E extends ValidContentEntrySlug | (string & {}), - >(entry: { - collection: C; - slug: E; - }): E extends ValidContentEntrySlug - ? Promise> - : Promise | undefined>; - export function getEntry< - C extends keyof DataEntryMap, - E extends keyof DataEntryMap[C] | (string & {}), - >(entry: { - collection: C; - id: E; - }): E extends keyof DataEntryMap[C] - ? Promise - : Promise | undefined>; - export function getEntry< - C extends keyof ContentEntryMap, - E extends ValidContentEntrySlug | (string & {}), - >( - collection: C, - slug: E, - ): E extends ValidContentEntrySlug - ? Promise> - : Promise | undefined>; - export function getEntry< - C extends keyof DataEntryMap, - E extends keyof DataEntryMap[C] | (string & {}), - >( - collection: C, - id: E, - ): E extends keyof DataEntryMap[C] - ? Promise - : Promise | undefined>; - - /** Resolve an array of entry references from the same collection */ - export function getEntries( - entries: { - collection: C; - slug: ValidContentEntrySlug; - }[], - ): Promise[]>; - export function getEntries( - entries: { - collection: C; - id: keyof DataEntryMap[C]; - }[], - ): Promise[]>; - - export function render( - entry: AnyEntryMap[C][string], - ): Promise; - - export function reference( - collection: C, - ): import('astro/zod').ZodEffects< - import('astro/zod').ZodString, - C extends keyof ContentEntryMap - ? { - collection: C; - slug: ValidContentEntrySlug; - } - : { - collection: C; - id: keyof DataEntryMap[C]; - } - >; - // Allow generic `string` to avoid excessive type errors in the config - // if `dev` is not running to update as you edit. - // Invalid collection names will be caught at build time. - export function reference( - collection: C, - ): import('astro/zod').ZodEffects; - - type ReturnTypeOrOriginal = T extends (...args: any[]) => infer R ? R : T; - type InferEntrySchema = import('astro/zod').infer< - ReturnTypeOrOriginal['schema']> - >; - - type ContentEntryMap = { - "post": { -"0h2p5w7rfh.md": { - id: "0h2p5w7rfh.md"; - slug: "0h2p5w7rfh"; - body: string; - collection: "post"; - data: InferEntrySchema<"post"> -} & { render(): Render[".md"] }; -"4d4y1g2up.md": { - id: "4d4y1g2up.md"; - slug: "4d4y1g2up"; - body: string; - collection: "post"; - data: InferEntrySchema<"post"> -} & { render(): Render[".md"] }; -"4sdndar2n.mdx": { - id: "4sdndar2n.mdx"; - slug: "4sdndar2n"; - body: string; - collection: "post"; - data: InferEntrySchema<"post"> -} & { render(): Render[".mdx"] }; -"fw7_gmrn2w.md": { - id: "fw7_gmrn2w.md"; - slug: "fw7_gmrn2w"; - body: string; - collection: "post"; - data: InferEntrySchema<"post"> -} & { render(): Render[".md"] }; -"kvc56ubf4.md": { - id: "kvc56ubf4.md"; - slug: "kvc56ubf4"; - body: string; - collection: "post"; - data: InferEntrySchema<"post"> -} & { render(): Render[".md"] }; -"m2juo4dy7c.mdx": { - id: "m2juo4dy7c.mdx"; - slug: "m2juo4dy7c"; - body: string; - collection: "post"; - data: InferEntrySchema<"post"> -} & { render(): Render[".mdx"] }; -"rkmss30pwd1.mdx": { - id: "rkmss30pwd1.mdx"; - slug: "rkmss30pwd1"; - body: string; - collection: "post"; - data: InferEntrySchema<"post"> -} & { render(): Render[".mdx"] }; -"rwft75ng_3.md": { - id: "rwft75ng_3.md"; - slug: "rwft75ng_3"; - body: string; - collection: "post"; - data: InferEntrySchema<"post"> -} & { render(): Render[".md"] }; -}; - - }; - - type DataEntryMap = { - - }; - - type AnyEntryMap = ContentEntryMap & DataEntryMap; - - export type ContentConfig = typeof import("../../src/content/config.js"); -} diff --git a/.astro/integrations/_inox-tools_astro-when/types.d.ts b/.astro/integrations/_inox-tools_astro-when/types.d.ts deleted file mode 100644 index 88d6927..0000000 --- a/.astro/integrations/_inox-tools_astro-when/types.d.ts +++ /dev/null @@ -1 +0,0 @@ -import '@inox-tools/astro-when'; \ No newline at end of file diff --git a/.astro/settings.json b/.astro/settings.json deleted file mode 100644 index eb029f0..0000000 --- a/.astro/settings.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "_variables": { - "lastUpdateCheck": 1726360437260 - } -} \ No newline at end of file diff --git a/.astro/types.d.ts b/.astro/types.d.ts deleted file mode 100644 index a82cceb..0000000 --- a/.astro/types.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -/// -/// -/// \ No newline at end of file diff --git a/.gitignore b/.gitignore index 7af008b..2bc0d75 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,5 @@ pnpm-debug.log* test-results/ playwright-report/ playwright/.cache/ + +.astro/ 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(); --- - +