nuxt-og-image 0.5.5 → 0.6.0
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/README.md +117 -6
- package/dist/module.d.ts +4 -0
- package/dist/module.json +1 -1
- package/dist/module.mjs +16 -4
- package/dist/runtime/browserUtil.mjs +3 -1
- package/dist/runtime/components/OgImage.d.ts +4 -9
- package/dist/runtime/components/OgImageScreenshot.d.ts +5 -9
- package/dist/runtime/components/OgImageScreenshot.mjs +2 -2
- package/dist/runtime/composables/defineOgImage.d.ts +2 -9
- package/dist/runtime/composables/defineOgImage.mjs +3 -2
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
<p align="center">
|
|
13
|
-
Generate dynamic social share images for you Nuxt
|
|
13
|
+
Generate dynamic social share images for you Nuxt 3 app.
|
|
14
14
|
</p>
|
|
15
15
|
|
|
16
16
|
<p align="center">
|
|
@@ -27,12 +27,15 @@ Generate dynamic social share images for you Nuxt v3 app.
|
|
|
27
27
|
</table>
|
|
28
28
|
</p>
|
|
29
29
|
|
|
30
|
+
ℹ️ Looking for a complete SEO solution? Check out [nuxt-seo-kit](https://github.com/harlan-zw/nuxt-seo-kit).
|
|
31
|
+
|
|
32
|
+
|
|
30
33
|
## Features
|
|
31
34
|
|
|
32
35
|
- 🧙 Pre-render `og:image`'s for your entire site in minutes with minimal config
|
|
33
36
|
- 🎨 Using a Vue component (powered by Nuxt Islands)
|
|
34
37
|
- 📸 OR just generate screenshots
|
|
35
|
-
-
|
|
38
|
+
- ⚙️ Screenshot options to hide elements, wait for animations, and more
|
|
36
39
|
|
|
37
40
|
🔨 Edge rendering is coming soon!
|
|
38
41
|
|
|
@@ -52,7 +55,8 @@ If you don't have a chromium binary installed on your system, run `npx playwrigh
|
|
|
52
55
|
### CI Build
|
|
53
56
|
|
|
54
57
|
If you are using this module in a CI context and the images aren't being generated,
|
|
55
|
-
you should
|
|
58
|
+
you should may need to install a chromium binary. You can do this by running `npx playwright install` or
|
|
59
|
+
`npm install playwright`.
|
|
56
60
|
|
|
57
61
|
_package.json_
|
|
58
62
|
|
|
@@ -254,11 +258,119 @@ The host of your site. This is required to generate the absolute path of the og:
|
|
|
254
258
|
- Type: `boolean`
|
|
255
259
|
- Default: `process.dev`
|
|
256
260
|
|
|
257
|
-
|
|
261
|
+
It allows you to generate images at runtime in production.
|
|
262
|
+
This uses a headless browser to generate images
|
|
258
263
|
and may have deployment issues.
|
|
259
264
|
|
|
260
265
|
⚠️ This is experimental and will likely not work in all environments.
|
|
261
266
|
|
|
267
|
+
## Screenshot Options
|
|
268
|
+
|
|
269
|
+
These can be provided as module options to set defaults
|
|
270
|
+
or set individually on the `OgImageScreenshot` or `OgImage` components or the `defineOgImage` or `defineOgImageScreenshot` composables.
|
|
271
|
+
|
|
272
|
+
```ts
|
|
273
|
+
// optionally set defaults globally
|
|
274
|
+
export default defineNuxtConfig({
|
|
275
|
+
ogImage: {
|
|
276
|
+
colorScheme: 'dark',
|
|
277
|
+
mask: '.screenshot-hidden'
|
|
278
|
+
}
|
|
279
|
+
})
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
### `colorScheme`
|
|
283
|
+
|
|
284
|
+
- Type: `'dark' | 'light'`
|
|
285
|
+
- Default: `undefined`
|
|
286
|
+
- Required: `false`
|
|
287
|
+
|
|
288
|
+
The color scheme to use when generating the image. This is useful for generating dark mode images.
|
|
289
|
+
|
|
290
|
+
```ts
|
|
291
|
+
defineOgImageScreenshot({
|
|
292
|
+
colorScheme: 'dark'
|
|
293
|
+
})
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
### `selector`
|
|
297
|
+
|
|
298
|
+
- Type: `string`
|
|
299
|
+
- Default: `undefined`
|
|
300
|
+
- Required: `false`
|
|
301
|
+
|
|
302
|
+
The selector to take a screenshot of. This is useful if you want to exclude header / footer elements.
|
|
303
|
+
|
|
304
|
+
```ts
|
|
305
|
+
defineOgImageScreenshot({
|
|
306
|
+
mask: '.page-content'
|
|
307
|
+
})
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
### `mask`
|
|
311
|
+
|
|
312
|
+
- Type: `string`
|
|
313
|
+
- Default: `undefined`
|
|
314
|
+
- Required: `false`
|
|
315
|
+
|
|
316
|
+
HTML selectors that should be removed from the image. Useful for removing popup banners or other elements that may be in the way.
|
|
317
|
+
|
|
318
|
+
```ts
|
|
319
|
+
defineOgImageScreenshot({
|
|
320
|
+
mask: '.popup-banner, .cookie-banner'
|
|
321
|
+
})
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
### `delay`
|
|
325
|
+
|
|
326
|
+
- Type: `number`
|
|
327
|
+
- Default: `undefined`
|
|
328
|
+
- Required: `false`
|
|
329
|
+
|
|
330
|
+
The delay to wait before taking the screenshot. This is useful if you want to wait for animations to complete.
|
|
331
|
+
|
|
332
|
+
```ts
|
|
333
|
+
defineOgImageScreenshot({
|
|
334
|
+
// wait 2 seconds
|
|
335
|
+
delay: 2000
|
|
336
|
+
})
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
### `alt`
|
|
340
|
+
|
|
341
|
+
- Type: `string`
|
|
342
|
+
- Default: `Web page screenshot of {route}.`
|
|
343
|
+
- Required: `false`
|
|
344
|
+
|
|
345
|
+
Used to generate the `og:image:alt` meta.
|
|
346
|
+
|
|
347
|
+
### `width`
|
|
348
|
+
|
|
349
|
+
- Type: `number`
|
|
350
|
+
- Default: `1200`
|
|
351
|
+
- Required: `true`
|
|
352
|
+
|
|
353
|
+
The default width of the image. This is useful if you want to generate a specific size image.
|
|
354
|
+
|
|
355
|
+
```ts
|
|
356
|
+
defineOgImageScreenshot({
|
|
357
|
+
width: 1500
|
|
358
|
+
})
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
### `height`
|
|
362
|
+
|
|
363
|
+
- Type: `number`
|
|
364
|
+
- Default: `630`
|
|
365
|
+
- Required: `true`
|
|
366
|
+
|
|
367
|
+
The default height of the image. This is useful if you want to generate a specific size image.
|
|
368
|
+
|
|
369
|
+
```ts
|
|
370
|
+
defineOgImageScreenshot({
|
|
371
|
+
height: 700
|
|
372
|
+
})
|
|
373
|
+
```
|
|
262
374
|
|
|
263
375
|
## Examples
|
|
264
376
|
|
|
@@ -277,7 +389,6 @@ and may have deployment issues.
|
|
|
277
389
|
- Pooya Parsa [Kachick](https://github.com/unjs/kachik)
|
|
278
390
|
- Nuxt Team
|
|
279
391
|
|
|
280
|
-
|
|
281
392
|
## License
|
|
282
393
|
|
|
283
|
-
MIT License ©
|
|
394
|
+
MIT License © 2023-PRESENT [Harlan Wilton](https://github.com/harlan-zw)
|
package/dist/module.d.ts
CHANGED
|
@@ -16,6 +16,10 @@ interface ScreenshotOptions {
|
|
|
16
16
|
* @default 630
|
|
17
17
|
*/
|
|
18
18
|
height: number;
|
|
19
|
+
/**
|
|
20
|
+
* How long to wait before taking the screenshot. Useful for waiting for animations.
|
|
21
|
+
*/
|
|
22
|
+
delay?: number;
|
|
19
23
|
}
|
|
20
24
|
declare module 'nitropack' {
|
|
21
25
|
interface NitroRouteRules {
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -41,6 +41,8 @@ async function screenshot(browser, url, options) {
|
|
|
41
41
|
timeout: 1e4,
|
|
42
42
|
waitUntil: "networkidle"
|
|
43
43
|
});
|
|
44
|
+
if (options.delay)
|
|
45
|
+
await page.waitForTimeout(options.delay);
|
|
44
46
|
if (options.mask) {
|
|
45
47
|
await page.evaluate((mask) => {
|
|
46
48
|
for (const el of document.querySelectorAll(mask))
|
|
@@ -48,7 +50,7 @@ async function screenshot(browser, url, options) {
|
|
|
48
50
|
}, options.mask);
|
|
49
51
|
}
|
|
50
52
|
if (options.selector)
|
|
51
|
-
await page.locator(options.selector).screenshot();
|
|
53
|
+
return await page.locator(options.selector).screenshot();
|
|
52
54
|
return await page.screenshot();
|
|
53
55
|
}
|
|
54
56
|
|
|
@@ -65,6 +67,13 @@ const Constants = {
|
|
|
65
67
|
DefaultRuntimeImageSuffix
|
|
66
68
|
};
|
|
67
69
|
|
|
70
|
+
function extractOgPayload(html) {
|
|
71
|
+
const payload = html.match(new RegExp(`<script id="${PayloadScriptId}" type="application/json">(.+?)<\/script>`))?.[1];
|
|
72
|
+
if (payload) {
|
|
73
|
+
return JSON.parse(payload);
|
|
74
|
+
}
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
68
77
|
const module = defineNuxtModule({
|
|
69
78
|
meta: {
|
|
70
79
|
name: "nuxt-og-image",
|
|
@@ -179,7 +188,7 @@ declare module 'nitropack' {
|
|
|
179
188
|
outputPath: joinURL(nitro.options.output.publicDir, config.outputDir, fileName),
|
|
180
189
|
linkingHtml: joinURL(nitro.options.output.publicDir, ctx.fileName),
|
|
181
190
|
route: ctx.route,
|
|
182
|
-
|
|
191
|
+
payload: extractOgPayload(ctx._contents),
|
|
183
192
|
routeRules: routeRules.ogImage || "",
|
|
184
193
|
screenshotPath: screenshotPath || ctx.route
|
|
185
194
|
};
|
|
@@ -215,7 +224,10 @@ declare module 'nitropack' {
|
|
|
215
224
|
const start = Date.now();
|
|
216
225
|
let hasError = false;
|
|
217
226
|
try {
|
|
218
|
-
const imgBuffer = await screenshot(browser, `${host}${entry.screenshotPath}`,
|
|
227
|
+
const imgBuffer = await screenshot(browser, `${host}${entry.screenshotPath}`, {
|
|
228
|
+
...config,
|
|
229
|
+
...entry.payload || {}
|
|
230
|
+
});
|
|
219
231
|
await writeFile(entry.outputPath, imgBuffer);
|
|
220
232
|
} catch (e) {
|
|
221
233
|
hasError = true;
|
|
@@ -227,7 +239,7 @@ declare module 'nitropack' {
|
|
|
227
239
|
));
|
|
228
240
|
}
|
|
229
241
|
} else {
|
|
230
|
-
nitro.logger.log(chalk.red("Failed to create browser to create og:images."));
|
|
242
|
+
nitro.logger.log(chalk.red("Failed to create a browser to create og:images."));
|
|
231
243
|
}
|
|
232
244
|
} catch (e) {
|
|
233
245
|
console.error(e);
|
|
@@ -10,6 +10,8 @@ export async function screenshot(browser, url, options) {
|
|
|
10
10
|
timeout: 1e4,
|
|
11
11
|
waitUntil: "networkidle"
|
|
12
12
|
});
|
|
13
|
+
if (options.delay)
|
|
14
|
+
await page.waitForTimeout(options.delay);
|
|
13
15
|
if (options.mask) {
|
|
14
16
|
await page.evaluate((mask) => {
|
|
15
17
|
for (const el of document.querySelectorAll(mask))
|
|
@@ -17,6 +19,6 @@ export async function screenshot(browser, url, options) {
|
|
|
17
19
|
}, options.mask);
|
|
18
20
|
}
|
|
19
21
|
if (options.selector)
|
|
20
|
-
await page.locator(options.selector).screenshot();
|
|
22
|
+
return await page.locator(options.selector).screenshot();
|
|
21
23
|
return await page.screenshot();
|
|
22
24
|
}
|
|
@@ -1,10 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<{
|
|
6
|
-
title?: string | undefined;
|
|
7
|
-
description?: string | undefined;
|
|
8
|
-
component?: string | undefined;
|
|
9
|
-
}>, {}>;
|
|
1
|
+
import type { OgImagePayload } from '../../types';
|
|
2
|
+
declare const _default: import("vue").DefineComponent<OgImagePayload, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<OgImagePayload>>, {
|
|
3
|
+
[x: string]: any;
|
|
4
|
+
}>;
|
|
10
5
|
export default _default;
|
|
@@ -1,10 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
}
|
|
6
|
-
title?: string | undefined;
|
|
7
|
-
description?: string | undefined;
|
|
8
|
-
component?: string | undefined;
|
|
9
|
-
}>, {}>;
|
|
1
|
+
import type { OgImageScreenshotPayload } from '../../types';
|
|
2
|
+
declare const _default: import("vue").DefineComponent<OgImageScreenshotPayload, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<OgImageScreenshotPayload>>, {
|
|
3
|
+
[x: string]: any;
|
|
4
|
+
[x: number]: any;
|
|
5
|
+
}>;
|
|
10
6
|
export default _default;
|
|
@@ -2,8 +2,8 @@ import { defineComponent } from "vue";
|
|
|
2
2
|
import { defineOgImageScreenshot } from "#imports";
|
|
3
3
|
export default defineComponent({
|
|
4
4
|
name: "OgImageScreenshot",
|
|
5
|
-
setup() {
|
|
6
|
-
defineOgImageScreenshot();
|
|
5
|
+
setup(_, { attrs }) {
|
|
6
|
+
defineOgImageScreenshot(attrs);
|
|
7
7
|
return () => null;
|
|
8
8
|
}
|
|
9
9
|
});
|
|
@@ -1,10 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
title?: string;
|
|
4
|
-
description?: string;
|
|
5
|
-
component?: string;
|
|
6
|
-
alt?: string;
|
|
7
|
-
[key: string]: any;
|
|
8
|
-
}
|
|
9
|
-
export declare function defineOgImageScreenshot(): void;
|
|
1
|
+
import type { OgImagePayload, OgImageScreenshotPayload } from '../../types';
|
|
2
|
+
export declare function defineOgImageScreenshot(options?: OgImageScreenshotPayload): void;
|
|
10
3
|
export declare function defineOgImage(options?: OgImagePayload): void;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { useServerHead } from "@vueuse/head";
|
|
2
2
|
import { useRouter } from "#imports";
|
|
3
3
|
import { DefaultRuntimeImageSuffix, HtmlRendererRoute, LinkPrerenderId, MetaOgImageContentPlaceholder, PayloadScriptId } from "#nuxt-og-image/constants";
|
|
4
|
-
export function defineOgImageScreenshot() {
|
|
4
|
+
export function defineOgImageScreenshot(options = {}) {
|
|
5
5
|
defineOgImage({
|
|
6
|
-
alt: "__OG_IMAGE_SCREENSHOT_ALT"
|
|
6
|
+
alt: "__OG_IMAGE_SCREENSHOT_ALT",
|
|
7
|
+
...options
|
|
7
8
|
});
|
|
8
9
|
}
|
|
9
10
|
export function defineOgImage(options = {}) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nuxt-og-image",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.6.0",
|
|
5
5
|
"packageManager": "pnpm@7.8.0",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"funding": "https://github.com/sponsors/harlan-zw",
|
|
@@ -29,26 +29,26 @@
|
|
|
29
29
|
"@nuxt/kit": "3.0.0",
|
|
30
30
|
"chalk": "^5.2.0",
|
|
31
31
|
"chrome-launcher": "^0.15.1",
|
|
32
|
-
"playwright-core": "^1.28.1",
|
|
33
32
|
"defu": "^6.1.1",
|
|
34
33
|
"execa": "^6.1.0",
|
|
35
34
|
"fast-glob": "^3.2.12",
|
|
36
35
|
"ohash": "^1.0.0",
|
|
37
36
|
"pathe": "^1.0.0",
|
|
37
|
+
"playwright-core": "^1.29.1",
|
|
38
38
|
"radix3": "^1.0.0",
|
|
39
39
|
"ufo": "^1.0.1"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"@antfu/eslint-config": "^0.
|
|
42
|
+
"@antfu/eslint-config": "^0.34.0",
|
|
43
43
|
"@nuxt/kit": "3.0.0",
|
|
44
44
|
"@nuxt/module-builder": "^0.2.1",
|
|
45
45
|
"@nuxt/test-utils": "3.0.0",
|
|
46
46
|
"@nuxtjs/eslint-config-typescript": "^12.0.0",
|
|
47
47
|
"bumpp": "^8.2.1",
|
|
48
|
-
"eslint": "8.
|
|
48
|
+
"eslint": "8.31.0",
|
|
49
49
|
"nuxt": "npm:nuxt3@latest",
|
|
50
|
-
"puppeteer": "^19.4.
|
|
51
|
-
"vitest": "^0.
|
|
50
|
+
"puppeteer": "^19.4.1",
|
|
51
|
+
"vitest": "^0.26.3"
|
|
52
52
|
},
|
|
53
53
|
"scripts": {
|
|
54
54
|
"lint": "eslint \"**/*.{ts,vue,json,yml}\"",
|