mirror of
https://github.com/ChenQihan666/MyBlog-Next.git
synced 2026-08-14 11:29:33 +08:00
fix: add an option to disable dynamic OG image generation (#476)
* fix: add an option to disable dynamic OG image generation Add new `dynamicOgImage` option in the `SITE` object inside `src/config.ts` file to disable auto og-image generation during build. Resolves #428 * docs: update guides for `SITE.dynamicOgImage` option
This commit is contained in:
@@ -16,4 +16,5 @@ export const SITE = {
|
|||||||
text: "Suggest Changes",
|
text: "Suggest Changes",
|
||||||
appendFilePath: true,
|
appendFilePath: true,
|
||||||
},
|
},
|
||||||
|
dynamicOgImage: true,
|
||||||
} as const;
|
} as const;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
---
|
---
|
||||||
author: Sat Naing
|
author: Sat Naing
|
||||||
pubDatetime: 2022-12-28T04:59:04.866Z
|
pubDatetime: 2022-12-28T04:59:04.866Z
|
||||||
|
modDatetime: 2025-03-12T13:39:20.763Z
|
||||||
title: Dynamic OG image generation in AstroPaper blog posts
|
title: Dynamic OG image generation in AstroPaper blog posts
|
||||||
slug: dynamic-og-image-generation-in-astropaper-blog-posts
|
slug: dynamic-og-image-generation-in-astropaper-blog-posts
|
||||||
featured: false
|
featured: false
|
||||||
@@ -80,6 +81,14 @@ async function loadGoogleFonts(
|
|||||||
|
|
||||||
> Check out [this PR](https://github.com/satnaing/astro-paper/pull/318) for more info.
|
> Check out [this PR](https://github.com/satnaing/astro-paper/pull/318) for more info.
|
||||||
|
|
||||||
|
## Trade-off
|
||||||
|
|
||||||
|
While this is a nice feature to have, there's a trade-off. Each OG image takes roughly one second to generate. This might not be noticeable at first, but as the number of blog posts grows, you might want to disable this feature. Since every OG image takes time to generate, having many of them will increase the build time linearly.
|
||||||
|
|
||||||
|
For example: If one OG image takes one second to generate, then 60 images will take around one minute, and 600 images will take approximately 10 minutes. This can significantly impact build times as your content scales.
|
||||||
|
|
||||||
|
Related issue: [#428](https://github.com/satnaing/astro-paper/issues/428)
|
||||||
|
|
||||||
## Limitations
|
## Limitations
|
||||||
|
|
||||||
At the time of writing this, [Satori](https://github.com/vercel/satori) is fairly new and has not reached major release yet. So, there are still some limitations to this dynamic OG image feature.
|
At the time of writing this, [Satori](https://github.com/vercel/satori) is fairly new and has not reached major release yet. So, there are still some limitations to this dynamic OG image feature.
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
author: Sat Naing
|
author: Sat Naing
|
||||||
pubDatetime: 2022-09-23T04:58:53Z
|
pubDatetime: 2022-09-23T04:58:53Z
|
||||||
modDatetime: 2025-03-07T14:01:26.494Z
|
modDatetime: 2025-03-12T13:39:39.057Z
|
||||||
title: How to configure AstroPaper theme
|
title: How to configure AstroPaper theme
|
||||||
slug: how-to-configure-astropaper-theme
|
slug: how-to-configure-astropaper-theme
|
||||||
featured: true
|
featured: true
|
||||||
@@ -42,13 +42,14 @@ export const SITE = {
|
|||||||
text: "Suggest Changes",
|
text: "Suggest Changes",
|
||||||
appendFilePath: true,
|
appendFilePath: true,
|
||||||
},
|
},
|
||||||
|
dynamicOgImage: true, // enable automatic dynamic og-image generation
|
||||||
} as const;
|
} as const;
|
||||||
```
|
```
|
||||||
|
|
||||||
Here are SITE configuration options
|
Here are SITE configuration options
|
||||||
|
|
||||||
| Options | Description |
|
| Options | Description |
|
||||||
| --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
| --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| `website` | Your deployed website URL |
|
| `website` | Your deployed website URL |
|
||||||
| `author` | Your name |
|
| `author` | Your name |
|
||||||
| `profile` | Your personal/portfolio website URL which is used for better SEO. Put `null` or empty string `""` if you don't have any. |
|
| `profile` | Your personal/portfolio website URL which is used for better SEO. Put `null` or empty string `""` if you don't have any. |
|
||||||
@@ -62,6 +63,7 @@ Here are SITE configuration options
|
|||||||
| `showArchives` | Determines whether to display the `Archives` menu (positioned between the `About` and `Search` menus) and its corresponding page on the site. This option is set to `true` by default. |
|
| `showArchives` | Determines whether to display the `Archives` menu (positioned between the `About` and `Search` menus) and its corresponding page on the site. This option is set to `true` by default. |
|
||||||
| `showBackButton` | Determines whether to display the `Go back` button in each blog post. |
|
| `showBackButton` | Determines whether to display the `Go back` button in each blog post. |
|
||||||
| `editPost` | This option allows users to suggest changes to a blog post by providing an edit link under blog post titles. This feature can be disabled by removing it from the `SITE` config. You can also set `appendFilePath` to `true` to automatically append the file path of the post to the url, directing users to the specific post they wish to edit. |
|
| `editPost` | This option allows users to suggest changes to a blog post by providing an edit link under blog post titles. This feature can be disabled by removing it from the `SITE` config. You can also set `appendFilePath` to `true` to automatically append the file path of the post to the url, directing users to the specific post they wish to edit. |
|
||||||
|
| `dynamicOgImage` | This option controls whether to [generate dynamic og-image](https://astro-paper.pages.dev/posts/dynamic-og-image-generation-in-astropaper-blog-posts/) if no `ogImage` is specified in the blog post frontmatter. If you have many blog posts, you might want to disable this feature. See the [trade-off](https://astro-paper.pages.dev/posts/dynamic-og-image-generation-in-astropaper-blog-posts/#trade-off) for more details. |
|
||||||
|
|
||||||
## Configuring locale
|
## Configuring locale
|
||||||
|
|
||||||
|
|||||||
@@ -23,14 +23,14 @@ const {
|
|||||||
author = SITE.author,
|
author = SITE.author,
|
||||||
profile = SITE.profile,
|
profile = SITE.profile,
|
||||||
description = SITE.desc,
|
description = SITE.desc,
|
||||||
ogImage = SITE.ogImage,
|
ogImage = SITE.ogImage ? `/${SITE.ogImage}` : "/og.png",
|
||||||
canonicalURL = new URL(Astro.url.pathname, Astro.url),
|
canonicalURL = new URL(Astro.url.pathname, Astro.url),
|
||||||
pubDatetime,
|
pubDatetime,
|
||||||
modDatetime,
|
modDatetime,
|
||||||
scrollSmooth = false,
|
scrollSmooth = false,
|
||||||
} = Astro.props;
|
} = Astro.props;
|
||||||
|
|
||||||
const socialImageURL = new URL(ogImage ?? SITE.ogImage ?? "og.png", Astro.url);
|
const socialImageURL = new URL(ogImage, Astro.url);
|
||||||
|
|
||||||
const structuredData = {
|
const structuredData = {
|
||||||
"@context": "https://schema.org",
|
"@context": "https://schema.org",
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ const {
|
|||||||
title,
|
title,
|
||||||
author,
|
author,
|
||||||
description,
|
description,
|
||||||
ogImage,
|
ogImage: initOgImage,
|
||||||
canonicalURL,
|
canonicalURL,
|
||||||
pubDatetime,
|
pubDatetime,
|
||||||
modDatetime,
|
modDatetime,
|
||||||
@@ -34,11 +34,24 @@ const {
|
|||||||
|
|
||||||
const { Content } = await render(post);
|
const { Content } = await render(post);
|
||||||
|
|
||||||
const ogImageUrl = typeof ogImage === "string" ? ogImage : ogImage?.src;
|
let ogImageUrl: string | undefined;
|
||||||
const ogUrl = new URL(
|
|
||||||
ogImageUrl ?? `/posts/${slugifyStr(title)}/index.png`,
|
// Determine OG image source
|
||||||
Astro.url.origin
|
if (typeof initOgImage === "string") {
|
||||||
).href;
|
ogImageUrl = initOgImage; // Remote OG image (absolute URL)
|
||||||
|
} else if (initOgImage?.src) {
|
||||||
|
ogImageUrl = initOgImage.src; // Local asset
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use dynamic OG image if enabled and no remote|local ogImage
|
||||||
|
if (!ogImageUrl && SITE.dynamicOgImage) {
|
||||||
|
ogImageUrl = `/posts/${slugifyStr(title)}/index.png`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Resolve OG image URL (or fallback to SITE.ogImage / default `og.png`)
|
||||||
|
const ogImage = ogImageUrl
|
||||||
|
? new URL(ogImageUrl, Astro.url.origin).href
|
||||||
|
: undefined;
|
||||||
|
|
||||||
const layoutProps = {
|
const layoutProps = {
|
||||||
title: `${title} | ${SITE.title}`,
|
title: `${title} | ${SITE.title}`,
|
||||||
@@ -47,7 +60,7 @@ const layoutProps = {
|
|||||||
pubDatetime,
|
pubDatetime,
|
||||||
modDatetime,
|
modDatetime,
|
||||||
canonicalURL,
|
canonicalURL,
|
||||||
ogImage: ogUrl,
|
ogImage,
|
||||||
scrollSmooth: true,
|
scrollSmooth: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,13 @@ import type { APIRoute } from "astro";
|
|||||||
import { getCollection, type CollectionEntry } from "astro:content";
|
import { getCollection, type CollectionEntry } from "astro:content";
|
||||||
import { generateOgImageForPost } from "@/utils/generateOgImages";
|
import { generateOgImageForPost } from "@/utils/generateOgImages";
|
||||||
import { slugifyStr } from "@/utils/slugify";
|
import { slugifyStr } from "@/utils/slugify";
|
||||||
|
import { SITE } from "@/config";
|
||||||
|
|
||||||
export async function getStaticPaths() {
|
export async function getStaticPaths() {
|
||||||
|
if (!SITE.dynamicOgImage) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
const posts = await getCollection("blog").then(p =>
|
const posts = await getCollection("blog").then(p =>
|
||||||
p.filter(({ data }) => !data.draft && !data.ogImage)
|
p.filter(({ data }) => !data.draft && !data.ogImage)
|
||||||
);
|
);
|
||||||
@@ -14,7 +19,18 @@ export async function getStaticPaths() {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
export const GET: APIRoute = async ({ props }) =>
|
export const GET: APIRoute = async ({ props }) => {
|
||||||
new Response(await generateOgImageForPost(props as CollectionEntry<"blog">), {
|
if (!SITE.dynamicOgImage) {
|
||||||
headers: { "Content-Type": "image/png" },
|
return new Response(null, {
|
||||||
|
status: 404,
|
||||||
|
statusText: "Not found",
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Response(
|
||||||
|
await generateOgImageForPost(props as CollectionEntry<"blog">),
|
||||||
|
{
|
||||||
|
headers: { "Content-Type": "image/png" },
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user