@docubook/plugin-og-image 0.0.0-stage → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +66 -2
- package/dist/cards.d.ts +54 -0
- package/dist/index.d.ts +40 -0
- package/dist/index.js +1022 -0
- package/dist/index.js.map +1 -0
- package/dist/layouts.d.ts +27 -0
- package/dist/options.d.ts +58 -0
- package/dist/publish.d.ts +39 -0
- package/dist/renderer.d.ts +26 -0
- package/dist/site.d.ts +78 -0
- package/package.json +61 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Wildan Nursahidan
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,67 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @docubook/plugin-og-image
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Social preview cards for [DocuBook Flame](https://github.com/DocuBook/docubook/tree/main/packages/flame). Every page gets a 1200×630 OpenGraph image built from its frontmatter, with your logo, site name and theme colours. Authors write nothing extra: `title` and `description` are enough.
|
|
4
|
+
|
|
5
|
+
Cards are rendered at build time with [Takumi](https://github.com/kane50613/takumi), a native renderer that needs no browser. A card takes a few milliseconds, and a build only renders the cards whose text or branding changed.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install -D @docubook/plugin-og-image
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
```json
|
|
14
|
+
{
|
|
15
|
+
"meta": {
|
|
16
|
+
"baseURL": "https://docs.example.com"
|
|
17
|
+
},
|
|
18
|
+
"plugins": ["@docubook/plugin-og-image"]
|
|
19
|
+
}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Set `meta.baseURL`: social sites only read absolute image URLs.
|
|
23
|
+
|
|
24
|
+
## What it does
|
|
25
|
+
|
|
26
|
+
- Sets each docs page's `image` to its card, so Flame writes the `og:image` tag as it does for an image you set yourself.
|
|
27
|
+
- Adds `og:image:width`, `og:image:height`, `og:image:type` and `og:image:alt`.
|
|
28
|
+
- Gives the landing page a card too, unless `meta.ogImage` already sets its image.
|
|
29
|
+
- Writes the cards to `<docs prefix>/assets/og/`, e.g. `/docs/assets/og/guides/setup.1a2b3c4d.png`. The hash in the name changes with the card's text, so social sites fetch the new card instead of a cached one.
|
|
30
|
+
- Serves the same cards from `flame dev`.
|
|
31
|
+
|
|
32
|
+
A page keeps its own image when its frontmatter sets `image`. `og: false` turns the card off for one page; `og.title` and `og.description` change the card's text without touching the page.
|
|
33
|
+
|
|
34
|
+
```yaml
|
|
35
|
+
---
|
|
36
|
+
title: Configuration reference for docu.json
|
|
37
|
+
description: Every option in docu.json.
|
|
38
|
+
og:
|
|
39
|
+
title: Configuration
|
|
40
|
+
---
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Options
|
|
44
|
+
|
|
45
|
+
| Option | Type | Default | Description |
|
|
46
|
+
| --- | --- | --- | --- |
|
|
47
|
+
| `layout` | `"card"` \| `"minimal"` | `"card"` | `card` adds the section name, a page-kind chip, a logo tile and a brand bar. `minimal` shows logo, title, description and domain on a plain background. |
|
|
48
|
+
| `logo` | string \| `false` | `navbar.logo.src` | Logo file: a project path (`brand/logo.svg`) or a site path (`/docs/assets/logo.svg`). SVG, PNG, JPEG or WebP, at most 1 MB. `false` renders no logo. |
|
|
49
|
+
| `siteName` | string | `navbar.logoText`, then `meta.title` | Name in the card's top row. |
|
|
50
|
+
| `pages` | `{ docs?, index?, home? }` | all `true` | Which pages get a card. |
|
|
51
|
+
| `fonts` | `{ path, weight?, style? }[]` | none | Fonts tried before the built-in Geist, which covers Latin-1 only. Add one for titles in other scripts. |
|
|
52
|
+
|
|
53
|
+
The build warns when a title has characters no loaded font can draw, and names the pages.
|
|
54
|
+
|
|
55
|
+
## How it works
|
|
56
|
+
|
|
57
|
+
`transformFrontmatter` sets `image: ./assets/og/<slug>.<hash>.png`, which Flame resolves against `meta.baseURL` and the docs prefix. Cards take their text from the frontmatter in the source file, so a title another plugin changes at build time (in `onLoad` or `transformFrontmatter`) does not reach the card; the file name the page links to and the file `onEnd` writes always match. `onEnd` reads every page's frontmatter, renders the cards that are missing or out of date, deletes cards of removed pages, and records what it wrote in `.docu/og-image.json`. Takumi's `render()` never touches the network: the logo and fonts are read from disk.
|
|
58
|
+
|
|
59
|
+
## Development
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
pnpm --filter @docubook/plugin-og-image build
|
|
63
|
+
pnpm --filter @docubook/plugin-og-image test
|
|
64
|
+
UPDATE_GOLDEN=1 pnpm --filter @docubook/plugin-og-image test # after an intended layout change
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
The golden-image tests compare against `src/__tests__/__golden__/` on Linux x64 only, where CI runs.
|
package/dist/cards.d.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Turning a page into a card: what text it shows, whether it is skipped, and
|
|
3
|
+
* the file name it is published under. Pure functions over frontmatter.
|
|
4
|
+
*/
|
|
5
|
+
import type { DocuConfig } from "@docubook/flame";
|
|
6
|
+
import type { ResolvedOptions } from "./options";
|
|
7
|
+
import { type Site } from "./site";
|
|
8
|
+
export type CardKind = "docs" | "index" | "home";
|
|
9
|
+
export interface Card {
|
|
10
|
+
kind: CardKind;
|
|
11
|
+
/** Docs slug; `""` for the docs index and the landing page. */
|
|
12
|
+
slug: string;
|
|
13
|
+
title: string;
|
|
14
|
+
description: string;
|
|
15
|
+
/** Top-level sidebar group, docs pages only. */
|
|
16
|
+
section: string | undefined;
|
|
17
|
+
}
|
|
18
|
+
export interface PlannedCard {
|
|
19
|
+
card: Card;
|
|
20
|
+
/** File name below `assets/og/`, e.g. `guide/routing.1a2b3c4d.png`. */
|
|
21
|
+
file: string;
|
|
22
|
+
/** Hash of everything flame's page cache also sees; its first 8 chars name the file. */
|
|
23
|
+
nameHash: string;
|
|
24
|
+
}
|
|
25
|
+
export type SkipReason = "disabled" | "author-image" | "opt-out";
|
|
26
|
+
/**
|
|
27
|
+
* Why a page gets no card, or `undefined` when it gets one. An image the
|
|
28
|
+
* author set always wins; `og: false` opts the page out.
|
|
29
|
+
*/
|
|
30
|
+
export declare function skipReason(kind: CardKind, frontmatter: Record<string, unknown>, options: ResolvedOptions): SkipReason | undefined;
|
|
31
|
+
/** Card text for a docs page or the docs index. Mirrors flame's title fallback. */
|
|
32
|
+
export declare function docsCard(kind: "docs" | "index", slug: string, frontmatter: Record<string, unknown>, site: Site): Card;
|
|
33
|
+
/** Card text for the landing page: the hero headline and the site description. */
|
|
34
|
+
export declare function homeCard(config: DocuConfig): Card;
|
|
35
|
+
export declare function sha256(...parts: Array<string | Uint8Array>): string;
|
|
36
|
+
/**
|
|
37
|
+
* Plan a card's file. The name hash covers only inputs that also invalidate
|
|
38
|
+
* flame's page cache (plugin version, `docu.json`, the page's source), so a
|
|
39
|
+
* page served from that cache always points at a file this build writes.
|
|
40
|
+
*/
|
|
41
|
+
export declare function planCard(card: Card, site: Site, options: ResolvedOptions, version: string): PlannedCard;
|
|
42
|
+
/** The value set as `frontmatter.image`; flame resolves it against the docs prefix. */
|
|
43
|
+
export declare function imageRef(file: string): string;
|
|
44
|
+
/** Source file candidates for a slug, in the order flame's scanner would find them. */
|
|
45
|
+
export declare function sourceCandidates(docsDir: string, slug: string): string[];
|
|
46
|
+
/**
|
|
47
|
+
* Frontmatter of a docs page as written in its source file, or `undefined`
|
|
48
|
+
* when no source exists. Every card is planned from this, never from the
|
|
49
|
+
* frontmatter other plugins hand on, so the page phase and `onEnd` always
|
|
50
|
+
* agree on the file name.
|
|
51
|
+
*/
|
|
52
|
+
export declare function readFrontmatter(docsDir: string, slug: string): Promise<Record<string, unknown> | undefined>;
|
|
53
|
+
/** {@link readFrontmatter} for hooks that must return synchronously. */
|
|
54
|
+
export declare function readFrontmatterSync(docsDir: string, slug: string): Record<string, unknown> | undefined;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @docubook/plugin-og-image
|
|
3
|
+
*
|
|
4
|
+
* Gives every page a 1200×630 social preview card, rendered at build time
|
|
5
|
+
* from the page's frontmatter with Takumi. Authors write nothing extra:
|
|
6
|
+
*
|
|
7
|
+
* - `transformFrontmatter` points `frontmatter.image` at the page's card, and
|
|
8
|
+
* flame's own SEO code turns it into an absolute `og:image`;
|
|
9
|
+
* - `injectHead` adds the card's size, type and alt text, and an `og:image`
|
|
10
|
+
* on the landing page when `meta.ogImage` does not set one;
|
|
11
|
+
* - `onEnd` renders the cards into `<docs>/assets/og/`, skipping the ones
|
|
12
|
+
* whose inputs did not change;
|
|
13
|
+
* - `handleRequest` renders a card on demand during `flame dev`.
|
|
14
|
+
*
|
|
15
|
+
* An `image` in frontmatter always wins, and `og: false` opts a page out.
|
|
16
|
+
*/
|
|
17
|
+
import type { DocuBookPlugin, DocuConfig } from "@docubook/flame";
|
|
18
|
+
import { type Palette } from "./layouts";
|
|
19
|
+
import { type OgImageOptions } from "./options";
|
|
20
|
+
import { type Engine, type LoadedFont } from "./renderer";
|
|
21
|
+
export type { FontOption, Layout, OgImageOptions, PagesOption } from "./options";
|
|
22
|
+
/** Logos above this size are skipped: a card shows them at 140 px. */
|
|
23
|
+
export declare const MAX_LOGO_BYTES: number;
|
|
24
|
+
export interface Logger {
|
|
25
|
+
info(message: string): void;
|
|
26
|
+
warn(message: string): void;
|
|
27
|
+
}
|
|
28
|
+
export interface PluginInternals {
|
|
29
|
+
/** @internal Project root instead of the `docu.json` lookup from `cwd` (tests). */
|
|
30
|
+
root?: string;
|
|
31
|
+
/** @internal Log sink (tests). */
|
|
32
|
+
log?: Logger;
|
|
33
|
+
/** @internal Renderer factory (tests). */
|
|
34
|
+
createEngine?: (fonts: LoadedFont[]) => Promise<Engine>;
|
|
35
|
+
/** @internal Plugin version that goes into card names (tests). */
|
|
36
|
+
version?: string;
|
|
37
|
+
}
|
|
38
|
+
/** Light-mode colours of the active theme, as flame resolves it. */
|
|
39
|
+
export declare function resolvePalette(config: DocuConfig): Palette;
|
|
40
|
+
export default function pluginOgImage(options?: OgImageOptions, internals?: PluginInternals): DocuBookPlugin;
|