nuxt-og-image 0.3.4 → 0.4.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 social share images for your pre-rendered Nuxt v3 app.
13
+ Generate dynamic social share images for you Nuxt v3 app.
14
14
  </p>
15
15
 
16
16
  <p align="center">
@@ -18,7 +18,7 @@ Generate social share images for your pre-rendered Nuxt v3 app.
18
18
  <tbody>
19
19
  <td align="center">
20
20
  <img width="800" height="0" /><br>
21
- <i>Status:</i> Early Access</b> <br>
21
+ <i>Status:</i> 🤫 Early Access - Active Development 🤫</b> <br>
22
22
  <sup> Please report any issues 🐛</sup><br>
23
23
  <sub>Made possible by my <a href="https://github.com/sponsors/harlan-zw">Sponsor Program 💖</a><br> Follow me <a href="https://twitter.com/harlan_zw">@harlan_zw</a> 🐦 • Join <a href="https://discord.gg/275MBUBvgP">Discord</a> for help</sub><br>
24
24
  <img width="800" height="0" />
@@ -29,12 +29,14 @@ Generate social share images for your pre-rendered Nuxt v3 app.
29
29
 
30
30
  ## Features
31
31
 
32
- - 🔄 Configure using route rules
33
- - 📸 Generates site screenshots
34
- - 🎨 OR build your own template with Vue (powered by Nuxt islands)
32
+ - 🧙 Generate images for your entire site in minutes with minimal config
33
+ - 🎨 Build your own template with Vue (powered by Nuxt Islands)
34
+ - 📸 OR just generates page screenshots
35
35
 
36
36
  ## Install
37
37
 
38
+ ⚠️ This module is still in development. Please get in touch with me over [Twitter](https://twitter.com/harlan_zw) or Discord if you are going to attempt to use this.
39
+
38
40
  ```bash
39
41
  npm install --save-dev nuxt-og-image
40
42
 
@@ -54,7 +56,29 @@ export default defineNuxtConfig({
54
56
  })
55
57
  ```
56
58
 
57
- To have routes included for og:image creation automatically, they need to be pre-rendered by Nitro.
59
+ ### Add your host name
60
+
61
+ The `og:image` meta tag requires the full URL, so you must provide your site host.
62
+
63
+ _nuxt.config.ts_
64
+
65
+ ```ts
66
+ export default defineNuxtConfig({
67
+ // Recommended
68
+ runtimeConfig: {
69
+ siteUrl: 'https://example.com',
70
+ },
71
+ // OR
72
+ ogImage: {
73
+ host: 'https://example.com',
74
+ },
75
+ })
76
+ ```
77
+
78
+ ### Pre-render routes
79
+
80
+ While the module is in early access, you should ensure that you pre-render any pages you want to
81
+ generate images for.
58
82
 
59
83
  ```ts
60
84
  export default defineNuxtConfig({
@@ -71,38 +95,73 @@ export default defineNuxtConfig({
71
95
  })
72
96
  ```
73
97
 
74
- ## Default Behaviour
98
+ ### Recommended: Enable Nuxt Islands
75
99
 
76
- By default, all pre-rendered routes will generate an og:image of a screenshot of the page.
100
+ To be able to preview the image in development and generate template images, you'll need
101
+ to enable Nuxt Islands.
77
102
 
78
- ## Using a template
103
+ If you're using Nuxt 3.0.0, you will need to switch to the [edge-release channel](https://nuxt.com/docs/guide/going-further/edge-channel#edge-release-channel).
79
104
 
80
- You can create your own template to use for generating og:image. This is done with
81
- Nuxt islands.
105
+ Once that's done, you can enable the flag for islands.
82
106
 
83
- ### Requirements
107
+ _nuxt.config.ts_
84
108
 
85
- To use this feature you will need to opt in to the edge channel, see [the instructions](https://nuxt.com/docs/guide/going-further/edge-channel#edge-release-channel).
109
+ ```ts
110
+ export default defineNuxtConfig({
111
+ experimental: {
112
+ componentIslands: true
113
+ },
114
+ })
115
+ ```
86
116
 
87
- The `componentIslands` experimental feature is required for this module to work and will is enabled for you.
117
+ ## Generating Screenshots
88
118
 
89
- ### Setup
119
+ ```vue
120
+ <script lang="ts" setup>
121
+ defineOgImageScreenshot()
122
+ </script>
123
+ <template>
124
+ <div>
125
+ <!-- Your page / app.vue / layout -->
126
+ </div>
127
+ </template>
128
+ ```
129
+
130
+ ## Generating Template Images
131
+
132
+ The template image generator is powered by Nuxt Islands. This means that you can use any Vue
133
+ component you want to generate your images.
134
+
135
+ ```vue
136
+ <script lang="ts" setup>
137
+ defineOgImage({
138
+ component: 'OgImage', // Nuxt Island component
139
+ // pass in any custom props
140
+ myCustomTitle: 'My Title'
141
+ })
142
+ </script>
143
+ <template>
144
+ <div>
145
+ <!-- Your page / app.vue / layout -->
146
+ </div>
147
+ </template>
148
+ ```
90
149
 
91
- #### Create the Island component
150
+ ### Creating your own template
92
151
 
93
- Firstly, you're going to create the Vue component to be used to render the og:image.
152
+ Create a new component with `.island.vue` as the suffix, such as `components/Banner.island.vue`.
94
153
 
95
- Create the file at `components/islands/OgImageDefault.vue`.
154
+ Use the below template to test it works, then modify it how you like.
96
155
 
97
156
  ```vue
98
157
  <script setup lang="ts">
99
158
  const props = defineProps({
100
- // payload props
159
+ // these will always be provided
101
160
  path: String,
102
161
  title: String,
103
162
  description: String,
104
- // add your own props here
105
- myCustomProp: String
163
+ // anything custom comes here
164
+ backgroundImage: String
106
165
  })
107
166
  </script>
108
167
 
@@ -125,143 +184,50 @@ const props = defineProps({
125
184
  align-items: center;
126
185
  justify-content: center;
127
186
  color: white;
128
- font-weight: bold;
129
- font-family: sans-serif;
130
187
  background: linear-gradient(to bottom, #30e8bf, #ff8235);
131
188
  }
132
189
 
133
190
  h1 {
134
191
  font-size: 4rem;
135
- margin: 0;
136
192
  }
137
193
  </style>
138
194
  ```
139
195
 
140
- #### Configure the payload
141
-
142
- Within a page
143
-
144
- ### Set host
196
+ Make sure you reference this component when using `defineOgImage` and any props to pass.
145
197
 
146
- You'll need to provide the host of your site in order to generate the sitemap.xml.
147
-
148
- ```ts
149
- export default defineNuxtConfig({
150
- // Recommended
151
- runtimeConfig: {
152
- siteUrl: 'https://example.com',
153
- },
154
- // OR
155
- sitemap: {
156
- hostname: 'https://example.com',
157
- },
158
- })
159
- ```
160
-
161
-
162
- ## Route Rules
163
-
164
- To change the behavior of the sitemap, you can use route rules. Route rules are provided as [Nitro route rules](https://v3.nuxtjs.org/docs/directory-structure/nitro/#route-rules).
165
-
166
- _nuxt.config.ts_
167
-
168
- ```ts
169
- export default defineNuxtConfig({
170
- routeRules: {
171
- // Don't add any /secret/** URLs to the sitemap
172
- '/secret/**': { index: false },
173
- // modify the sitemap entry for specific URLs
174
- '/about': { sitemap: { changefreq: 'daily', priority: 0.3 } }
175
- }
198
+ ```vue
199
+ <script lang="ts" setup>
200
+ defineOgImage({
201
+ component: 'Banner',
202
+ backgroundImage: 'https://example.com/my-background-image.jpg',
176
203
  })
204
+ </script>
177
205
  ```
178
206
 
179
- The following options are available for each route rule:
207
+ ## Previewing Images
180
208
 
181
- - `index`: Whether to include the route in the sitemap.xml. Defaults to `true`.
182
- - `sitemap.changefreq`: The change frequency of the route.
183
- - `sitemap.priority`: The priority of the route.
209
+ Once you have defined the og:image using the composable, you can preview the image by visiting
210
+ the following URLs:
211
+ - `/your-path/__og-image` Renders the HTML output
212
+ - `/your-path/og-image.png` Renders the og:image
184
213
 
185
214
  ## Module Config
186
215
 
187
- If you need further control over the sitemap URLs, you can provide config on the `sitemap` key.
188
-
189
216
  ### `host`
190
217
 
191
218
  - Type: `string`
192
219
  - Default: `undefined`
193
220
  - Required: `true`
194
221
 
195
- The host of your site. This is required to generate the sitemap.xml.
196
-
197
- ### `trailingSlash`
198
-
199
- - Type: `boolean`
200
- - Default: `false`
201
-
202
- Whether to add a trailing slash to the URLs in the sitemap.xml.
222
+ The host of your site. This is required to generate the absolute path of the og:image.
203
223
 
204
- ### `enabled`
224
+ ### `runtimeImages`
205
225
 
206
226
  - Type: `boolean`
207
- - Default: `true`
208
-
209
- Whether to generate the sitemap.xml.
210
-
211
- ### `include`
212
-
213
- - Type: `string[]`
214
- - Default: `undefined`
215
-
216
- Filter routes that match the given rules.
217
-
218
- ```ts
219
- export default defineNuxtConfig({
220
- sitemap: {
221
- include: [
222
- '/my-hidden-url'
223
- ]
224
- }
225
- })
226
- ```
227
-
228
- ### `exclude`
229
-
230
- - Type: `string[]`
231
- - Default: `undefined`
232
-
233
- Filter routes that match the given rules.
234
-
235
- ```ts
236
- export default defineNuxtConfig({
237
- sitemap: {
238
- exclude: [
239
- '/my-secret-section/**'
240
- ]
241
- }
242
- })
243
- ```
244
-
245
- Additional config extends [sitemap.js](https://github.com/ekalinin/sitemap.js).
227
+ - Default: `process.dev`
246
228
 
247
- ## Examples
248
-
249
- ### Add custom routes without pre-rendering
250
-
251
- ```ts
252
- export default defineNuxtConfig({
253
- hooks: {
254
- 'sitemap:generate': (ctx) => {
255
- // add custom URLs
256
- ctx.urls.push({
257
- url: '/my-custom-url',
258
- changefreq: 'daily',
259
- priority: 0.3
260
- })
261
- }
262
- }
263
- })
264
- ```
229
+ Allows you to generate images at runtime in production. This uses a headless browser to generate images
230
+ and may have deployment issues.
265
231
 
266
232
  ## Sponsors
267
233
 
@@ -271,6 +237,11 @@ export default defineNuxtConfig({
271
237
  </a>
272
238
  </p>
273
239
 
240
+ ## Credits
241
+
242
+ - Pooya Parsa [Kachick](https://github.com/unjs/kachik)
243
+ - Nuxt Team
244
+
274
245
 
275
246
  ## License
276
247
 
package/dist/module.d.ts CHANGED
@@ -25,7 +25,6 @@ declare module 'nitropack' {
25
25
  }
26
26
 
27
27
  interface ModuleOptions extends ScreenshotOptions {
28
- defaultIslandComponent: string;
29
28
  /**
30
29
  * The directory within `public` where the og images will be stored.
31
30
  *
@@ -41,10 +40,6 @@ interface ModuleOptions extends ScreenshotOptions {
41
40
  */
42
41
  runtimeImages: boolean;
43
42
  }
44
- declare const HtmlRendererRoute = "__og_image";
45
- declare const PayloadScriptId = "nuxt-og-image-payload";
46
- declare const MetaOgImageContentPlaceholder = "__NUXT_OG_IMAGE_PLACEHOLDER__";
47
- declare const LinkPrerenderId = "nuxt-og-image-screenshot-path";
48
43
  declare const _default: _nuxt_schema.NuxtModule<ModuleOptions>;
49
44
 
50
- export { HtmlRendererRoute, LinkPrerenderId, MetaOgImageContentPlaceholder, ModuleOptions, PayloadScriptId, _default as default };
45
+ export { ModuleOptions, _default as default };
package/dist/module.json CHANGED
@@ -5,5 +5,5 @@
5
5
  "bridge": false
6
6
  },
7
7
  "configKey": "ogImage",
8
- "version": "0.3.4"
8
+ "version": "0.4.0"
9
9
  }
package/dist/module.mjs CHANGED
@@ -5,8 +5,9 @@ import { hash } from 'ohash';
5
5
  import chalk from 'chalk';
6
6
  import defu from 'defu';
7
7
  import { toRouteMatcher, createRouter } from 'radix3';
8
- import { withBase } from 'ufo';
8
+ import { withBase, joinURL } from 'ufo';
9
9
  import fg from 'fast-glob';
10
+ import { join } from 'pathe';
10
11
 
11
12
  async function createBrowser() {
12
13
  if (!process.env.AWS_LAMBDA_FUNCTION_NAME)
@@ -46,6 +47,15 @@ const HtmlRendererRoute = "__og_image";
46
47
  const PayloadScriptId = "nuxt-og-image-payload";
47
48
  const MetaOgImageContentPlaceholder = "__NUXT_OG_IMAGE_PLACEHOLDER__";
48
49
  const LinkPrerenderId = "nuxt-og-image-screenshot-path";
50
+ const DefaultRuntimeImageSuffix = "og-image.png";
51
+ const Constants = {
52
+ HtmlRendererRoute,
53
+ PayloadScriptId,
54
+ MetaOgImageContentPlaceholder,
55
+ LinkPrerenderId,
56
+ DefaultRuntimeImageSuffix
57
+ };
58
+
49
59
  const module = defineNuxtModule({
50
60
  meta: {
51
61
  name: "nuxt-og-image",
@@ -106,19 +116,32 @@ declare module 'nitropack' {
106
116
  filePath: resolve("./runtime/components/OgImage.vue"),
107
117
  island: true
108
118
  });
119
+ const runtimeDir = resolve("./runtime");
120
+ nuxt.options.build.transpile.push(runtimeDir);
121
+ const constScript = Object.entries(Constants).map(([k, v]) => `export const ${k} = '${v}'`).join("\n");
122
+ nuxt.options.alias["#nuxt-og-image/constants"] = addTemplate({
123
+ filename: "nuxt-og-image-constants.mjs",
124
+ getContents: () => constScript
125
+ }).dst;
126
+ nuxt.hooks.hook("nitro:config", (nitroConfig) => {
127
+ nitroConfig.externals = defu(nitroConfig.externals || {}, {
128
+ inline: [runtimeDir]
129
+ });
130
+ nitroConfig.virtual["#nuxt-og-image/constants"] = constScript;
131
+ });
109
132
  nuxt.hooks.hook("nitro:init", async (nitro) => {
110
133
  let entries = [];
111
134
  const _routeRulesMatcher = toRouteMatcher(
112
135
  createRouter({ routes: nitro.options.routeRules })
113
136
  );
114
- const outputPath = `${nitro.options.output.dir}/public/${config.outputDir}`;
137
+ const outputPath = join(nitro.options.output.publicDir, config.outputDir);
115
138
  nitro.hooks.hook("prerender:generate", async (ctx) => {
116
139
  if (ctx.route.includes(".") || ctx.route.endsWith(HtmlRendererRoute))
117
140
  return;
118
141
  let html = ctx.contents;
119
142
  if (!html)
120
143
  return;
121
- if (!html.includes('id="nuxt-og-image-payload"'))
144
+ if (!html.includes(`id="${PayloadScriptId}"`))
122
145
  return;
123
146
  const routeRules = defu({}, ..._routeRulesMatcher.matchAll(ctx.route).reverse());
124
147
  if (routeRules.ogImage === false)
@@ -129,8 +152,8 @@ declare module 'nitropack' {
129
152
  const entry = {
130
153
  fileName,
131
154
  absoluteUrl,
132
- outputPath: `${nitro.options.output.dir}/public/${config.outputDir}/${fileName}`,
133
- linkingHtml: ctx.fileName,
155
+ outputPath: joinURL(nitro.options.output.publicDir, config.outputDir, fileName),
156
+ linkingHtml: joinURL(nitro.options.output.publicDir, ctx.fileName),
134
157
  route: ctx.route,
135
158
  hasPayload: screenshotPath,
136
159
  routeRules: routeRules.ogImage || "",
@@ -149,7 +172,8 @@ declare module 'nitropack' {
149
172
  await mkdir(outputPath, { recursive: true });
150
173
  } catch (e) {
151
174
  }
152
- const previewProcess = execa("npx", ["serve", `${nitro.options.output.dir}/public`]);
175
+ const previewProcess = execa("npx", ["serve", nitro.options.output.publicDir]);
176
+ let browser = null;
153
177
  try {
154
178
  previewProcess.stderr?.pipe(process.stderr);
155
179
  const host = (await new Promise((resolve2) => {
@@ -159,39 +183,40 @@ declare module 'nitropack' {
159
183
  }
160
184
  });
161
185
  })).trim();
162
- const browser = await createBrowser();
186
+ browser = await createBrowser();
163
187
  nitro.logger.info(`Generating ${entries.length} og:images...`);
164
- try {
165
- for (const k in entries) {
166
- const entry = entries[k];
167
- const start = Date.now();
188
+ for (const k in entries) {
189
+ const entry = entries[k];
190
+ const start = Date.now();
191
+ let hasError = false;
192
+ try {
168
193
  const imgBuffer = await screenshot(browser, `${host}${entry.screenshotPath}`, config);
169
194
  await writeFile(entry.outputPath, imgBuffer);
170
- const generateTimeMS = Date.now() - start;
171
- nitro.logger.log(chalk.gray(
172
- ` ${Number(k) === entries.length - 1 ? "\u2514\u2500" : "\u251C\u2500"} /${config.outputDir}/${entry.fileName} (${generateTimeMS}ms) ${Math.round(Number(k) / (entries.length - 1) * 100)}%`
173
- ));
195
+ } catch (e) {
196
+ hasError = true;
197
+ console.error(e);
174
198
  }
175
- } catch (e) {
176
- console.error(e);
177
- } finally {
178
- await browser.close();
199
+ const generateTimeMS = Date.now() - start;
200
+ nitro.logger.log(chalk[hasError ? "red" : "gray"](
201
+ ` ${Number(k) === entries.length - 1 ? "\u2514\u2500" : "\u251C\u2500"} /${config.outputDir}/${entry.fileName} (${generateTimeMS}ms) ${Math.round(Number(k) / (entries.length - 1) * 100)}%`
202
+ ));
179
203
  }
180
204
  } catch (e) {
181
205
  console.error(e);
182
206
  } finally {
207
+ await browser?.close();
183
208
  previewProcess.kill();
184
209
  }
185
- for (const entry of entries.filter((e) => e.hasPayload)) {
186
- const html = await readFile(`${nitro.options.output.dir}/public${entry.linkingHtml}`, "utf-8");
210
+ for (const entry of entries) {
211
+ const html = await readFile(entry.linkingHtml, "utf-8");
187
212
  const newHtml = html.replace(new RegExp(`<link id="${LinkPrerenderId}" rel="prerender" href="(.*?)">`), "").replace(new RegExp(`<script id="${PayloadScriptId}" type="application/json">(.*?)<\/script>`), "").replace("\n\n", "\n");
188
213
  if (html !== newHtml) {
189
- await writeFile(`${nitro.options.output.dir}/public${entry.linkingHtml}`, newHtml, { encoding: "utf-8" });
214
+ await writeFile(entry.linkingHtml, newHtml, { encoding: "utf-8" });
190
215
  }
191
216
  }
192
- const ogImageFolders = await fg([`**/${HtmlRendererRoute}`], { cwd: nitro.options.output.dir, onlyDirectories: true });
217
+ const ogImageFolders = await fg([`**/${HtmlRendererRoute}`], { cwd: nitro.options.output.publicDir, onlyDirectories: true });
193
218
  for (const ogImageFolder of ogImageFolders)
194
- await rm(`${nitro.options.output.dir}/${ogImageFolder}`, { recursive: true, force: true });
219
+ await rm(join(nitro.options.output.publicDir, ogImageFolder), { recursive: true, force: true });
195
220
  entries = [];
196
221
  };
197
222
  nitro.hooks.hook("rollup:before", async () => {
@@ -204,4 +229,4 @@ declare module 'nitropack' {
204
229
  }
205
230
  });
206
231
 
207
- export { HtmlRendererRoute, LinkPrerenderId, MetaOgImageContentPlaceholder, PayloadScriptId, module as default };
232
+ export { module as default };
@@ -0,0 +1,5 @@
1
+ /// <reference types="node" />
2
+ import type { Browser } from 'playwright-core';
3
+ import type { ScreenshotOptions } from '../types';
4
+ export declare function createBrowser(): Promise<Browser>;
5
+ export declare function screenshot(browser: Browser, url: string, options: ScreenshotOptions): Promise<Buffer>;
@@ -0,0 +1,33 @@
1
+ export async function createBrowser() {
2
+ if (!process.env.AWS_LAMBDA_FUNCTION_NAME)
3
+ process.env.AWS_LAMBDA_FUNCTION_NAME = "test";
4
+ const playwright = await import("playwright-core");
5
+ const awsChrome = await import("chrome-aws-lambda");
6
+ return await playwright.chromium.launch({
7
+ args: awsChrome.args,
8
+ executablePath: await awsChrome.executablePath,
9
+ headless: awsChrome.headless
10
+ });
11
+ }
12
+ export async function screenshot(browser, url, options) {
13
+ const page = await browser.newPage({
14
+ colorScheme: options.colorScheme
15
+ });
16
+ await page.setViewportSize({
17
+ width: options.width,
18
+ height: options.height
19
+ });
20
+ await page.goto(url, {
21
+ timeout: 1e4,
22
+ waitUntil: "networkidle"
23
+ });
24
+ if (options.mask) {
25
+ await page.evaluate((mask) => {
26
+ for (const el of document.querySelectorAll(mask))
27
+ el.style.display = "none";
28
+ }, options.mask);
29
+ }
30
+ if (options.selector)
31
+ await page.locator(options.selector).screenshot();
32
+ return await page.screenshot();
33
+ }
@@ -1,8 +1,3 @@
1
- export declare const HtmlRendererRoute = "__og_image";
2
- export declare const RuntimeImageSuffix = "og-image.png";
3
- export declare const PayloadScriptId = "nuxt-og-image-payload";
4
- export declare const MetaOgImageContentPlaceholder = "__NUXT_OG_IMAGE_PLACEHOLDER__";
5
- export declare const LinkPrerenderId = "nuxt-og-image-screenshot-path";
6
1
  export interface OgImagePayload {
7
2
  runtime?: boolean;
8
3
  title?: string;
@@ -1,10 +1,6 @@
1
1
  import { useServerHead } from "@vueuse/head";
2
2
  import { useRouter } from "#imports";
3
- export const HtmlRendererRoute = "__og_image";
4
- export const RuntimeImageSuffix = "og-image.png";
5
- export const PayloadScriptId = "nuxt-og-image-payload";
6
- export const MetaOgImageContentPlaceholder = "__NUXT_OG_IMAGE_PLACEHOLDER__";
7
- export const LinkPrerenderId = "nuxt-og-image-screenshot-path";
3
+ import { DefaultRuntimeImageSuffix, HtmlRendererRoute, LinkPrerenderId, MetaOgImageContentPlaceholder, PayloadScriptId } from "#nuxt-og-image/constants";
8
4
  export function defineOgImageScreenshot() {
9
5
  defineOgImage();
10
6
  }
@@ -16,7 +12,7 @@ export function defineOgImage(options = {}) {
16
12
  meta: [
17
13
  {
18
14
  property: "og:image",
19
- content: () => options.runtime ? `${route}/${RuntimeImageSuffix}` : MetaOgImageContentPlaceholder
15
+ content: () => options.runtime ? `${route}/${DefaultRuntimeImageSuffix}` : MetaOgImageContentPlaceholder
20
16
  }
21
17
  ],
22
18
  link: options.component ? [
@@ -1,5 +1,3 @@
1
- export declare const HtmlRendererRoute = "__og_image";
2
- export declare const PayloadScriptId = "nuxt-og-image-payload";
3
1
  export declare const extractOgPayload: (html: string) => any;
4
2
  export declare const inferOgPayload: (html: string) => Record<string, any>;
5
3
  declare const _default: import("h3").EventHandler<string | undefined>;
@@ -1,9 +1,8 @@
1
- import { withoutTrailingSlash, withQuery } from "ufo";
1
+ import { withQuery, withoutTrailingSlash } from "ufo";
2
2
  import { renderSSRHead } from "@unhead/ssr";
3
3
  import { createHeadCore } from "@unhead/vue";
4
4
  import { defineEventHandler, getQuery } from "h3";
5
- export const HtmlRendererRoute = "__og_image";
6
- export const PayloadScriptId = "nuxt-og-image-payload";
5
+ import { HtmlRendererRoute, PayloadScriptId } from "#nuxt-og-image/constants";
7
6
  export const extractOgPayload = (html) => {
8
7
  const payload = html.match(new RegExp(`<script id="${PayloadScriptId}" type="application/json">(.+?)<\/script>`))?.[1];
9
8
  if (payload) {
@@ -1,9 +1,3 @@
1
1
  /// <reference types="node" />
2
- import type { Browser } from 'playwright-core';
3
- import type { ScreenshotOptions } from '../../types';
4
- export declare const HtmlRendererRoute = "__og_image";
5
- export declare const RuntimeImageSuffix = "og-image.png";
6
- export declare function screenshot(browser: Browser, url: string, options: ScreenshotOptions): Promise<Buffer>;
7
- export declare function createBrowser(): Promise<Browser>;
8
2
  declare const _default: import("h3").EventHandler<Buffer | undefined>;
9
3
  export default _default;
@@ -1,39 +1,6 @@
1
1
  import { defineEventHandler, getRequestHeader, setHeader } from "h3";
2
- export const HtmlRendererRoute = "__og_image";
3
- export const RuntimeImageSuffix = "og-image.png";
4
- export async function screenshot(browser, url, options) {
5
- const page = await browser.newPage({
6
- colorScheme: options.colorScheme
7
- });
8
- await page.setViewportSize({
9
- width: options.width,
10
- height: options.height
11
- });
12
- await page.goto(url, {
13
- timeout: 1e4,
14
- waitUntil: "networkidle"
15
- });
16
- if (options.mask) {
17
- await page.evaluate((mask) => {
18
- for (const el of document.querySelectorAll(mask))
19
- el.style.display = "none";
20
- }, options.mask);
21
- }
22
- if (options.selector)
23
- await page.locator(options.selector).screenshot();
24
- return await page.screenshot();
25
- }
26
- export async function createBrowser() {
27
- if (!process.env.AWS_LAMBDA_FUNCTION_NAME)
28
- process.env.AWS_LAMBDA_FUNCTION_NAME = "test";
29
- const playwright = await import("playwright-core");
30
- const awsChrome = await import("chrome-aws-lambda");
31
- return await playwright.chromium.launch({
32
- args: awsChrome.args,
33
- executablePath: await awsChrome.executablePath,
34
- headless: awsChrome.headless
35
- });
36
- }
2
+ import { createBrowser, screenshot } from "../browserService.mjs";
3
+ import { HtmlRendererRoute, RuntimeImageSuffix } from "#nuxt-og-image/constants";
37
4
  export default defineEventHandler(async (e) => {
38
5
  if (!e.path?.endsWith(RuntimeImageSuffix))
39
6
  return;
package/dist/types.d.ts CHANGED
@@ -7,4 +7,4 @@ declare module '@nuxt/schema' {
7
7
  }
8
8
 
9
9
 
10
- export { HtmlRendererRoute, LinkPrerenderId, MetaOgImageContentPlaceholder, ModuleOptions, PayloadScriptId, default } from './module'
10
+ export { ModuleOptions, default } from './module'
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "nuxt-og-image",
3
3
  "type": "module",
4
- "version": "0.3.4",
4
+ "version": "0.4.0",
5
5
  "packageManager": "pnpm@7.8.0",
6
6
  "license": "MIT",
7
7
  "funding": "https://github.com/sponsors/harlan-zw",
@@ -33,16 +33,11 @@
33
33
  "execa": "^6.1.0",
34
34
  "fast-glob": "^3.2.12",
35
35
  "ohash": "^1.0.0",
36
+ "pathe": "^1.0.0",
36
37
  "playwright-core": "^1.28.1",
37
38
  "radix3": "^1.0.0",
38
39
  "ufo": "^1.0.1"
39
40
  },
40
- "unbuild": {
41
- "externals": [
42
- "playwright-core",
43
- "chrome-aws-lambda"
44
- ]
45
- },
46
41
  "devDependencies": {
47
42
  "@antfu/eslint-config": "^0.33.1",
48
43
  "@nuxt/kit": "3.0.0",
@@ -52,7 +47,6 @@
52
47
  "bumpp": "^8.2.1",
53
48
  "eslint": "8.29.0",
54
49
  "nuxt": "npm:nuxt3@latest",
55
- "pathe": "^1.0.0",
56
50
  "puppeteer": "^19.4.0",
57
51
  "vitest": "^0.25.5"
58
52
  },