fix(ogImage): update socialImage path to include base URL if defined (#1858)
* fix(ogImage): update socialImage path to include base URL if defined * feat(path): add function to check if a file path is absolute * fix(ogImage): handle absolute paths for user defined og image paths * docs(CustomOgImages): update socialImage property to accept full URLs * fix(ogImage): typo * fix(ogImage): improve user-defined OG image path handling * Update docs/plugins/CustomOgImages.md Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com> * Update quartz/plugins/emitters/ogImage.tsx Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com> * refactor(path): remove isAbsoluteFilePath function * fix(ogImage): update user-defined OG image path handling to support relative URLs * feat(ogImage): enhance user-defined OG image path handling with absolute URL support * refactor(ogImage): remove debug log for ogImagePath * feat(path): add isAbsoluteURL function and corresponding tests * refactor(path): remove unused URL import for isomorphic compatibility --------- Co-authored-by: Karim H <karimh96@hotmail.com> Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com>
This commit is contained in:
parent
9316ddf2f5
commit
3ce6aa49bf
4 changed files with 31 additions and 4 deletions
|
@ -62,7 +62,7 @@ The following properties can be used to customize your link previews:
|
||||||
| `socialDescription` | `description` | Description to be used for preview. |
|
| `socialDescription` | `description` | Description to be used for preview. |
|
||||||
| `socialImage` | `image`, `cover` | Link to preview image. |
|
| `socialImage` | `image`, `cover` | Link to preview image. |
|
||||||
|
|
||||||
The `socialImage` property should contain a link to an image relative to `quartz/static`. If you have a folder for all your images in `quartz/static/my-images`, an example for `socialImage` could be `"my-images/cover.png"`.
|
The `socialImage` property should contain a link to an image either relative to `quartz/static`, or a full URL. If you have a folder for all your images in `quartz/static/my-images`, an example for `socialImage` could be `"my-images/cover.png"`. Alternatively, you can use a fully qualified URL like `"https://example.com/cover.png"`.
|
||||||
|
|
||||||
> [!info] Info
|
> [!info] Info
|
||||||
>
|
>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { QuartzEmitterPlugin } from "../types"
|
import { QuartzEmitterPlugin } from "../types"
|
||||||
import { i18n } from "../../i18n"
|
import { i18n } from "../../i18n"
|
||||||
import { unescapeHTML } from "../../util/escape"
|
import { unescapeHTML } from "../../util/escape"
|
||||||
import { FullSlug, getFileExtension, joinSegments, QUARTZ } from "../../util/path"
|
import { FullSlug, getFileExtension, isAbsoluteURL, joinSegments, QUARTZ } from "../../util/path"
|
||||||
import { ImageOptions, SocialImageOptions, defaultImage, getSatoriFonts } from "../../util/og"
|
import { ImageOptions, SocialImageOptions, defaultImage, getSatoriFonts } from "../../util/og"
|
||||||
import sharp from "sharp"
|
import sharp from "sharp"
|
||||||
import satori, { SatoriOptions } from "satori"
|
import satori, { SatoriOptions } from "satori"
|
||||||
|
@ -144,13 +144,19 @@ export const CustomOgImages: QuartzEmitterPlugin<Partial<SocialImageOptions>> =
|
||||||
additionalHead: [
|
additionalHead: [
|
||||||
(pageData) => {
|
(pageData) => {
|
||||||
const isRealFile = pageData.filePath !== undefined
|
const isRealFile = pageData.filePath !== undefined
|
||||||
const userDefinedOgImagePath = pageData.frontmatter?.socialImage
|
let userDefinedOgImagePath = pageData.frontmatter?.socialImage
|
||||||
|
|
||||||
|
if (userDefinedOgImagePath) {
|
||||||
|
userDefinedOgImagePath = isAbsoluteURL(userDefinedOgImagePath)
|
||||||
|
? userDefinedOgImagePath
|
||||||
|
: `https://${baseUrl}/static/${userDefinedOgImagePath}`
|
||||||
|
}
|
||||||
|
|
||||||
const generatedOgImagePath = isRealFile
|
const generatedOgImagePath = isRealFile
|
||||||
? `https://${baseUrl}/${pageData.slug!}-og-image.webp`
|
? `https://${baseUrl}/${pageData.slug!}-og-image.webp`
|
||||||
: undefined
|
: undefined
|
||||||
const defaultOgImagePath = `https://${baseUrl}/static/og-image.png`
|
const defaultOgImagePath = `https://${baseUrl}/static/og-image.png`
|
||||||
const ogImagePath = userDefinedOgImagePath ?? generatedOgImagePath ?? defaultOgImagePath
|
const ogImagePath = userDefinedOgImagePath ?? generatedOgImagePath ?? defaultOgImagePath
|
||||||
|
|
||||||
const ogImageMimeType = `image/${getFileExtension(ogImagePath) ?? "png"}`
|
const ogImageMimeType = `image/${getFileExtension(ogImagePath) ?? "png"}`
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|
|
@ -38,6 +38,17 @@ describe("typeguards", () => {
|
||||||
assert(!path.isRelativeURL("./abc/def.md"))
|
assert(!path.isRelativeURL("./abc/def.md"))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test("isAbsoluteURL", () => {
|
||||||
|
assert(path.isAbsoluteURL("https://example.com"))
|
||||||
|
assert(path.isAbsoluteURL("http://example.com"))
|
||||||
|
assert(path.isAbsoluteURL("ftp://example.com/a/b/c"))
|
||||||
|
assert(path.isAbsoluteURL("http://host/%25"))
|
||||||
|
assert(path.isAbsoluteURL("file://host/twoslashes?more//slashes"))
|
||||||
|
|
||||||
|
assert(!path.isAbsoluteURL("example.com/abc/def"))
|
||||||
|
assert(!path.isAbsoluteURL("abc"))
|
||||||
|
})
|
||||||
|
|
||||||
test("isFullSlug", () => {
|
test("isFullSlug", () => {
|
||||||
assert(path.isFullSlug("index"))
|
assert(path.isFullSlug("index"))
|
||||||
assert(path.isFullSlug("abc/def"))
|
assert(path.isFullSlug("abc/def"))
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { slug as slugAnchor } from "github-slugger"
|
import { slug as slugAnchor } from "github-slugger"
|
||||||
import type { Element as HastElement } from "hast"
|
import type { Element as HastElement } from "hast"
|
||||||
import { clone } from "./clone"
|
import { clone } from "./clone"
|
||||||
|
|
||||||
// this file must be isomorphic so it can't use node libs (e.g. path)
|
// this file must be isomorphic so it can't use node libs (e.g. path)
|
||||||
|
|
||||||
export const QUARTZ = "quartz"
|
export const QUARTZ = "quartz"
|
||||||
|
@ -39,6 +40,15 @@ export function isRelativeURL(s: string): s is RelativeURL {
|
||||||
return validStart && validEnding && ![".md", ".html"].includes(getFileExtension(s) ?? "")
|
return validStart && validEnding && ![".md", ".html"].includes(getFileExtension(s) ?? "")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isAbsoluteURL(s: string): boolean {
|
||||||
|
try {
|
||||||
|
new URL(s)
|
||||||
|
} catch {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
export function getFullSlug(window: Window): FullSlug {
|
export function getFullSlug(window: Window): FullSlug {
|
||||||
const res = window.document.body.dataset.slug! as FullSlug
|
const res = window.document.body.dataset.slug! as FullSlug
|
||||||
return res
|
return res
|
||||||
|
|
Loading…
Add table
Reference in a new issue