nuxt-og-image 0.5.4 → 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 CHANGED
@@ -10,7 +10,7 @@
10
10
 
11
11
 
12
12
  <p align="center">
13
- Generate dynamic social share images for you Nuxt v3 app.
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
- - 📦 Choose your API: Composition or components
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 replace your build script with the following:
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
- Allows you to generate images at runtime in production. This uses a headless browser to generate images
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 © 2022-PRESENT [Harlan Wilton](https://github.com/harlan-zw)
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
@@ -5,5 +5,5 @@
5
5
  "bridge": false
6
6
  },
7
7
  "configKey": "ogImage",
8
- "version": "0.5.4"
8
+ "version": "0.6.0"
9
9
  }
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
- hasPayload: screenshotPath,
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}`, config);
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;
@@ -226,6 +238,8 @@ declare module 'nitropack' {
226
238
  ` ${Number(k) === entries.length - 1 ? "\u2514\u2500" : "\u251C\u2500"} /${config.outputDir}/${entry.fileName} (${generateTimeMS}ms) ${Math.round(Number(k) / (entries.length - 1) * 100)}%`
227
239
  ));
228
240
  }
241
+ } else {
242
+ nitro.logger.log(chalk.red("Failed to create a browser to create og:images."));
229
243
  }
230
244
  } catch (e) {
231
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
- declare const _default: import("vue").DefineComponent<{
2
- title?: string | undefined;
3
- description?: string | undefined;
4
- component?: string | undefined;
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
- declare const _default: import("vue").DefineComponent<{
2
- title?: string | undefined;
3
- description?: string | undefined;
4
- component?: string | undefined;
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 { 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
- export interface OgImagePayload {
2
- runtime?: boolean;
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.5.4",
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",
@@ -34,21 +34,21 @@
34
34
  "fast-glob": "^3.2.12",
35
35
  "ohash": "^1.0.0",
36
36
  "pathe": "^1.0.0",
37
+ "playwright-core": "^1.29.1",
37
38
  "radix3": "^1.0.0",
38
39
  "ufo": "^1.0.1"
39
40
  },
40
41
  "devDependencies": {
41
- "@antfu/eslint-config": "^0.33.1",
42
+ "@antfu/eslint-config": "^0.34.0",
42
43
  "@nuxt/kit": "3.0.0",
43
44
  "@nuxt/module-builder": "^0.2.1",
44
45
  "@nuxt/test-utils": "3.0.0",
45
46
  "@nuxtjs/eslint-config-typescript": "^12.0.0",
46
47
  "bumpp": "^8.2.1",
47
- "eslint": "8.29.0",
48
+ "eslint": "8.31.0",
48
49
  "nuxt": "npm:nuxt3@latest",
49
- "playwright-core": "^1.28.1",
50
- "puppeteer": "^19.4.0",
51
- "vitest": "^0.25.5"
50
+ "puppeteer": "^19.4.1",
51
+ "vitest": "^0.26.3"
52
52
  },
53
53
  "scripts": {
54
54
  "lint": "eslint \"**/*.{ts,vue,json,yml}\"",