@nolebase/vitepress-plugin-og-image
Version:
A vitepress plugin to generate Open Graph Protocol previewing images (a.k.a. social media cards) for your site.
136 lines (132 loc) • 5.88 kB
TypeScript
import { DefaultTheme, SiteConfig } from 'vitepress';
import { Buffer } from 'node:buffer';
interface BuildEndGenerateOpenGraphImagesOptions {
/**
* The base URL to use for open graph image.
*
* Must be a full URL, e.g. `https://example.com` or `https://example.com/path/of/baseUrl`.
*
* This is because for platforms like Telegram, Twitter, and Facebook, they wouldn't accept
* relative URLs for open graph image when dynamically fetching the image from the HTML meta tag.
* Instead, they require a full URL to the image.
*
* If you would ever need to use a dynamic base URL (e.g. Cloudflare Pages, Vercel, Netlify staging
* preview URL), you may need to create a separate stabled sub-domain or use a standalone services
* S3 to host the generated open graph images to make sure the image URL is full with domain.
*/
baseUrl: string;
/**
* The category options to use for open graph image.
*/
category?: BuildEndGenerateOpenGraphImagesOptionsCategory;
/**
* This function will be called with each URL of the image hrefs in the SVG template.
* You can return a Buffer of the image to use to avoid fetching the image from its URL.
* If you return undefined, the image will be fetched from its URL.
*/
svgImageUrlResolver?: (imageUrl: string) => Promise<Buffer> | Buffer | undefined;
/**
* Font buffers to load for rendering the template SVG
*/
svgFontBuffers?: Buffer[];
/**
* Temaplte SVG file path.
* If not supplied, will try to locate `og-template.svg` under `public` or `assets` directory,
* and will fallback to a builtin template.
*/
templateSvgPath?: string;
/**
* Width of the result image.
*
* @default 1200
*/
resultImageWidth?: number;
/**
* Maximum characters per line.
*
* @default 17
*/
maxCharactersPerLine?: number;
/**
* Whether to override existing meta tags.
*
* @default true
*/
overrideExistingMetaTags?: boolean;
}
interface BuildEndGenerateOpenGraphImagesOptionsCategory {
/**
* Automatically extract category text from path with a specific level.
*
* For example, if you have a path like `/foo/bar/baz/index.md`, and you set `byLevel` to `1`,
* the category text will be `bar`. This is extremely useful when you have a file based routing,
* while having all the contents organized in a stable directory structure (e.g. knowledge base).
*
* As end user, either specify one of `byLevel`, `byPathPrefix`, or `byCustomGetter`, if multiple
* options are provided, `byCustomGetter` would be used as the first priority. `byPathPrefix` secondary,
* and `byLevel` as the last resort. If none of them are provided or produced undefined result for category
* text, it will fallback to frontmatter category text.
*/
byLevel?: number;
/**
* Automatically extract category text from path with a specific prefix.
*
* For example, if you have a path like `/foo/bar/baz/index.md`, and you set `byPathPrefix` to `[{ prefix: 'foo', text: 'Foo' }]`,
* the category text will be `Foo`. This is extremely useful when you use file based routing, while organized the contents
* inside a directory name that friendly to browsers.
*
* As end user, either specify one of `byLevel`, `byPathPrefix`, or `byCustomGetter`, if multiple
* options are provided, `byCustomGetter` would be used as the first priority. `byPathPrefix` secondary,
* and `byLevel` as the last resort. If none of them are provided or produced undefined result for category
* text, it will fallback to frontmatter category text.
*/
byPathPrefix?: {
/**
* The prefix to match.
*/
prefix: string;
/**
* The text to use as category.
*/
text: string;
}[];
/**
* If `byLevel` or `byPathPrefix` is not enough, you can provide a custom getter to extract category text programmatically.
*
* For example you have a complex i18n system, or you want to extract category text from a specific field in frontmatter.
*
* As end user, either specify one of `byLevel`, `byPathPrefix`, or `byCustomGetter`, if multiple
* options are provided, `byCustomGetter` would be used as the first priority. `byPathPrefix` secondary,
* and `byLevel` as the last resort. If none of them are provided or produced undefined result for category
* text, it will fallback to frontmatter category text.
*
* @param {PageItem} page - The page item to process
* @returns {string} The category text
*/
byCustomGetter?: (page: PageItem) => string | void | Promise<string | void>;
/**
* Fallback to frontmatter category text when no category text found.
*
* Only effective when no category text found from `byLevel`, `byPathPrefix`, or `byCustomGetter`, or none of them
* were provided. If `true`, it will fallback to frontmatter category text when no category text found. Otherwise a 'Un-categorized'
* will be used as category text.
*
* @default true
*/
fallbackWithFrontmatter?: boolean;
}
interface PageItem extends DefaultTheme.SidebarItem {
title: string;
category: string;
locale: string;
sourceFilePath: string;
normalizedSourceFilePath: string;
frontmatter: Record<string, any>;
}
/**
* Build end generate open graph images.
* @param {BuildEndGenerateOpenGraphImagesOptions} options - Options used for generating open graph images.
* @returns Build end hook for VitePress
*/
declare function buildEndGenerateOpenGraphImages(options: BuildEndGenerateOpenGraphImagesOptions): (siteConfig: SiteConfig) => Promise<void>;
export { buildEndGenerateOpenGraphImages };