nuxt-og-image 0.5.5 → 1.0.0-beta.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.
Files changed (54) hide show
  1. package/README.md +147 -29
  2. package/dist/client/200.html +7 -0
  3. package/dist/client/404.html +7 -0
  4. package/dist/client/_nuxt/Icon.4a9650c6.js +1 -0
  5. package/dist/client/_nuxt/Icon.e17ad835.css +1 -0
  6. package/dist/client/_nuxt/entry.0827acf4.css +1 -0
  7. package/dist/client/_nuxt/entry.ce848650.js +4 -0
  8. package/dist/client/_nuxt/error-404.556d8899.js +1 -0
  9. package/dist/client/_nuxt/error-404.68aa58b4.css +1 -0
  10. package/dist/client/_nuxt/error-500.70731718.js +1 -0
  11. package/dist/client/_nuxt/error-500.dc5710d1.css +1 -0
  12. package/dist/client/_nuxt/error-component.418ebd67.js +3 -0
  13. package/dist/client/index.html +7 -0
  14. package/dist/client/nuxt.svg +3 -0
  15. package/dist/module.d.ts +17 -12
  16. package/dist/module.json +1 -1
  17. package/dist/module.mjs +212 -103
  18. package/dist/runtime/browserUtil.mjs +3 -1
  19. package/dist/runtime/components/OgImageDynamic.d.ts +5 -0
  20. package/dist/runtime/components/OgImageDynamic.mjs +9 -0
  21. package/dist/runtime/components/OgImageScreenshot.d.ts +5 -9
  22. package/dist/runtime/components/OgImageScreenshot.mjs +2 -2
  23. package/dist/runtime/components/OgImageStatic.d.ts +5 -0
  24. package/dist/runtime/components/{OgImage.mjs → OgImageStatic.mjs} +3 -3
  25. package/dist/runtime/components/OgImageTemplate.island.vue +8 -83
  26. package/dist/runtime/composables/defineOgImage.d.ts +4 -9
  27. package/dist/runtime/composables/defineOgImage.mjs +35 -11
  28. package/dist/runtime/{browsers → nitro/browsers}/default.d.ts +0 -0
  29. package/dist/runtime/{browsers → nitro/browsers}/default.mjs +0 -0
  30. package/dist/runtime/{browsers → nitro/browsers}/lambda.d.ts +0 -0
  31. package/dist/runtime/{browsers → nitro/browsers}/lambda.mjs +0 -0
  32. package/dist/runtime/nitro/providers/browser.d.ts +3 -0
  33. package/dist/runtime/nitro/providers/browser.mjs +16 -0
  34. package/dist/runtime/nitro/providers/satori.d.ts +3 -0
  35. package/dist/runtime/nitro/providers/satori.mjs +48 -0
  36. package/dist/runtime/nitro/routes/__og_image__/html.d.ts +2 -0
  37. package/dist/runtime/nitro/routes/__og_image__/html.mjs +43 -0
  38. package/dist/runtime/nitro/routes/__og_image__/index.d.ts +2 -0
  39. package/dist/runtime/nitro/routes/__og_image__/index.mjs +26 -0
  40. package/dist/runtime/nitro/routes/__og_image__/og.png.d.ts +2 -0
  41. package/dist/runtime/nitro/routes/__og_image__/og.png.mjs +23 -0
  42. package/dist/runtime/nitro/{html.d.ts → routes/__og_image__/payload.d.ts} +2 -1
  43. package/dist/runtime/nitro/routes/__og_image__/payload.mjs +53 -0
  44. package/dist/runtime/nitro/routes/__og_image__/svg.d.ts +2 -0
  45. package/dist/runtime/nitro/routes/__og_image__/svg.mjs +16 -0
  46. package/dist/runtime/nitro/utils.d.ts +8 -0
  47. package/dist/runtime/nitro/utils.mjs +18 -0
  48. package/dist/runtime/public/inter-latin-ext-400-normal.woff +0 -0
  49. package/dist/runtime/public/inter-latin-ext-700-normal.woff +0 -0
  50. package/package.json +18 -7
  51. package/dist/runtime/components/OgImage.d.ts +0 -10
  52. package/dist/runtime/nitro/html.mjs +0 -55
  53. package/dist/runtime/nitro/image.d.ts +0 -3
  54. package/dist/runtime/nitro/image.mjs +0 -18
package/dist/module.mjs CHANGED
@@ -1,13 +1,16 @@
1
- import { readFile, writeFile, rm, mkdir } from 'node:fs/promises';
2
- import { defineNuxtModule, createResolver, addTemplate, getNuxtVersion, addServerHandler, addImports, addComponent } from '@nuxt/kit';
1
+ import { mkdir, writeFile } from 'node:fs/promises';
2
+ import { existsSync } from 'fs';
3
+ import { useNuxt, addTemplate, defineNuxtModule, createResolver, addServerHandler, addImports, addComponent } from '@nuxt/kit';
3
4
  import { execa } from 'execa';
4
- 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, joinURL } from 'ufo';
9
- import fg from 'fast-glob';
10
- import { join } from 'pathe';
8
+ import { joinURL } from 'ufo';
9
+ import { resolve, relative } from 'pathe';
10
+ import { tinyws } from 'tinyws';
11
+ import sirv from 'sirv';
12
+ import { createBirpcGroup } from 'birpc';
13
+ import { stringify, parse } from 'flatted';
11
14
 
12
15
  async function createBrowser() {
13
16
  try {
@@ -41,6 +44,8 @@ async function screenshot(browser, url, options) {
41
44
  timeout: 1e4,
42
45
  waitUntil: "networkidle"
43
46
  });
47
+ if (options.delay)
48
+ await page.waitForTimeout(options.delay);
44
49
  if (options.mask) {
45
50
  await page.evaluate((mask) => {
46
51
  for (const el of document.querySelectorAll(mask))
@@ -48,23 +53,118 @@ async function screenshot(browser, url, options) {
48
53
  }, options.mask);
49
54
  }
50
55
  if (options.selector)
51
- await page.locator(options.selector).screenshot();
56
+ return await page.locator(options.selector).screenshot();
52
57
  return await page.screenshot();
53
58
  }
54
59
 
55
- const HtmlRendererRoute = "__og_image";
56
60
  const PayloadScriptId = "nuxt-og-image-payload";
57
- const MetaOgImageContentPlaceholder = "__NUXT_OG_IMAGE_PLACEHOLDER__";
58
- const LinkPrerenderId = "nuxt-og-image-screenshot-path";
59
- const DefaultRuntimeImageSuffix = "og-image.png";
60
61
  const Constants = {
61
- HtmlRendererRoute,
62
- PayloadScriptId,
63
- MetaOgImageContentPlaceholder,
64
- LinkPrerenderId,
65
- DefaultRuntimeImageSuffix
62
+ PayloadScriptId
66
63
  };
67
64
 
65
+ function exposeConfig(alias, filename, config) {
66
+ const exports = Object.entries(config).map(([k, v]) => `export const ${k} = '${v}'`).join("\n");
67
+ useNuxt().options.alias[alias] = addTemplate({
68
+ filename,
69
+ getContents: () => exports
70
+ }).dst;
71
+ useNuxt().hooks.hook("nitro:config", (nitroConfig) => {
72
+ nitroConfig.virtual[alias] = exports;
73
+ });
74
+ }
75
+
76
+ function setupPlaygroundRPC(nuxt, config) {
77
+ const serverFunctions = {
78
+ getConfig() {
79
+ return config;
80
+ },
81
+ async openInEditor(input) {
82
+ if (input.startsWith("./"))
83
+ input = resolve(process.cwd(), input);
84
+ const match = input.match(/^(.*?)([:\d]*)$/);
85
+ let suffix = "";
86
+ if (match) {
87
+ input = match[1];
88
+ suffix = match[2];
89
+ }
90
+ const file = [
91
+ input,
92
+ `${input}.js`,
93
+ `${input}.mjs`,
94
+ `${input}.ts`
95
+ ].find((i) => existsSync(i));
96
+ if (file) {
97
+ await import('launch-editor').then((r) => (r.default || r)(file + suffix));
98
+ } else {
99
+ console.error("File not found:", input);
100
+ }
101
+ }
102
+ };
103
+ const clients = /* @__PURE__ */ new Set();
104
+ const birpc = createBirpcGroup(serverFunctions, []);
105
+ nuxt.hook("builder:watch", (e, path) => {
106
+ if (e === "change")
107
+ birpc.boardcast.refresh.asEvent(path);
108
+ });
109
+ const middleware = async (req, res) => {
110
+ if (req.ws) {
111
+ const ws = await req.ws();
112
+ clients.add(ws);
113
+ const channel = {
114
+ post: (d) => ws.send(d),
115
+ on: (fn) => ws.on("message", fn),
116
+ serialize: stringify,
117
+ deserialize: parse
118
+ };
119
+ birpc.updateChannels((c) => {
120
+ c.push(channel);
121
+ });
122
+ ws.on("close", () => {
123
+ clients.delete(ws);
124
+ birpc.updateChannels((c) => {
125
+ const index = c.indexOf(channel);
126
+ if (index >= 0)
127
+ c.splice(index, 1);
128
+ });
129
+ });
130
+ } else if (req.method === "POST") {
131
+ const body = await getBodyJson(req);
132
+ if (body.method === "setPayload") ; else {
133
+ res.statusCode = 400;
134
+ }
135
+ res.end();
136
+ }
137
+ };
138
+ return {
139
+ middleware,
140
+ birpc
141
+ };
142
+ }
143
+ function getBodyJson(req) {
144
+ return new Promise((resolve2, reject) => {
145
+ let body = "";
146
+ req.on("data", (chunk) => body += chunk);
147
+ req.on("error", reject);
148
+ req.on("end", () => {
149
+ try {
150
+ resolve2(JSON.parse(body) || {});
151
+ } catch (e) {
152
+ reject(e);
153
+ }
154
+ });
155
+ });
156
+ }
157
+
158
+ function extractOgPayload(html) {
159
+ const payload = html.match(new RegExp(`<script id="${PayloadScriptId}" type="application/json">(.+?)<\/script>`))?.[1];
160
+ if (payload) {
161
+ return JSON.parse(payload);
162
+ }
163
+ return false;
164
+ }
165
+ const PATH = "/__nuxt_og_image__";
166
+ const PATH_ENTRY = `${PATH}/entry`;
167
+ const PATH_PLAYGROUND = `${PATH}/client`;
68
168
  const module = defineNuxtModule({
69
169
  meta: {
70
170
  name: "nuxt-og-image",
@@ -76,57 +176,74 @@ const module = defineNuxtModule({
76
176
  },
77
177
  defaults(nuxt) {
78
178
  return {
179
+ experimentalNitroBrowser: false,
180
+ forcePrerender: !nuxt.options.dev && nuxt.options._generate,
79
181
  host: nuxt.options.runtimeConfig.public?.siteUrl,
80
182
  width: 1200,
81
- height: 630,
82
- defaultIslandComponent: "OgImageTemplate",
83
- outputDir: "_og-images",
84
- serverSideRender: nuxt.options.dev || (process.env.NITRO_PRESET || "").includes("edge")
183
+ height: 630
85
184
  };
86
185
  },
87
186
  async setup(config, nuxt) {
88
187
  const { resolve } = createResolver(import.meta.url);
188
+ const distResolve = (p) => {
189
+ const cwd = resolve(".");
190
+ if (cwd.endsWith("/dist"))
191
+ return resolve(p);
192
+ return resolve(`../dist/${p}`);
193
+ };
89
194
  nuxt.options.experimental.componentIslands = true;
90
195
  const isEdge = (process.env.NITRO_PRESET || "").includes("edge");
91
196
  addTemplate({
92
197
  filename: "nuxt-og-image.d.ts",
93
198
  getContents: () => {
94
199
  return `// Generated by nuxt-og-image
200
+ interface NuxtOgImageNitroRules {
201
+ ogImage?: false | Record<string, any>
202
+ }
95
203
  declare module 'nitropack' {
96
- interface NitroRouteRules {
97
- ogImage?: 'screenshot' | string | false
98
- }
204
+ interface NitroRouteRules extends NuxtOgImageNitroRules {}
205
+ interface NitroRouteConfig extends NuxtOgImageNitroRules {}
99
206
  }
207
+ export {}
100
208
  `;
101
209
  }
102
210
  });
103
211
  nuxt.hooks.hook("prepare:types", ({ references }) => {
104
212
  references.push({ path: resolve(nuxt.options.buildDir, "nuxt-og-image.d.ts") });
105
213
  });
106
- if (getNuxtVersion(nuxt) !== "3.0.0") {
214
+ ["html", "payload", "svg", "og.png"].forEach((type) => {
107
215
  addServerHandler({
108
- handler: resolve("./runtime/nitro/html")
216
+ handler: resolve(`./runtime/nitro/routes/__og_image__/${type}`)
109
217
  });
110
- if (config.serverSideRender) {
111
- addServerHandler({
112
- handler: resolve("./runtime/nitro/image")
113
- });
114
- }
115
- }
116
- addImports({
117
- name: "defineOgImage",
118
- from: resolve("./runtime/composables/defineOgImage")
119
218
  });
120
- addImports({
121
- name: "defineOgImageScreenshot",
122
- from: resolve("./runtime/composables/defineOgImage")
219
+ if (nuxt.options.dev) {
220
+ const playgroundDir = distResolve("./client");
221
+ const {
222
+ middleware: rpcMiddleware
223
+ } = setupPlaygroundRPC(nuxt, config);
224
+ nuxt.hook("vite:serverCreated", (server) => {
225
+ server.middlewares.use(PATH_ENTRY, tinyws());
226
+ server.middlewares.use(PATH_ENTRY, rpcMiddleware);
227
+ if (existsSync(playgroundDir))
228
+ server.middlewares.use(PATH_PLAYGROUND, sirv(playgroundDir, { single: true, dev: true }));
229
+ });
230
+ addServerHandler({
231
+ handler: resolve("./runtime/nitro/routes/__og_image__/index")
232
+ });
233
+ }
234
+ ["defineOgImageDynamic", "defineOgImageStatic", "defineOgImageScreenshot"].forEach((name) => {
235
+ addImports({
236
+ name,
237
+ from: resolve("./runtime/composables/defineOgImage")
238
+ });
123
239
  });
124
240
  await addComponent({
125
241
  name: "OgImageTemplate",
126
242
  filePath: resolve("./runtime/components/OgImageTemplate.island.vue"),
243
+ global: true,
127
244
  island: true
128
245
  });
129
- ["OgImage", "OgImageScreenshot"].forEach((name) => {
246
+ ["OgImageStatic", "OgImageDynamic", "OgImageScreenshot"].forEach((name) => {
130
247
  addComponent({
131
248
  name,
132
249
  filePath: resolve(`./runtime/components/${name}`),
@@ -135,67 +252,65 @@ declare module 'nitropack' {
135
252
  });
136
253
  const runtimeDir = resolve("./runtime");
137
254
  nuxt.options.build.transpile.push(runtimeDir);
138
- const constScript = Object.entries(Constants).map(([k, v]) => `export const ${k} = '${v}'`).join("\n");
139
- nuxt.options.alias["#nuxt-og-image/constants"] = addTemplate({
140
- filename: "nuxt-og-image-constants.mjs",
141
- getContents: () => constScript
142
- }).dst;
255
+ exposeConfig("#nuxt-og-image/constants", "nuxt-og-image-constants.mjs", Constants);
256
+ exposeConfig("#nuxt-og-image/config", "nuxt-og-image-config.mjs", config);
143
257
  nuxt.hooks.hook("nitro:config", (nitroConfig) => {
144
258
  nitroConfig.externals = defu(nitroConfig.externals || {}, {
145
259
  inline: [runtimeDir]
146
260
  });
147
- nitroConfig.virtual["#nuxt-og-image/constants"] = constScript;
148
- nitroConfig.virtual["#nuxt-og-image/browser"] = `export { createBrowser } from '${runtimeDir}/browsers/${isEdge ? "lambda" : "default"}'`;
149
- if (isEdge) {
150
- ["puppeteer", "bufferutil", "utf-8-validate"].forEach((name) => {
151
- nitroConfig.alias[name] = "unenv/runtime/mock/proxy";
152
- });
261
+ nitroConfig.publicAssets = nitroConfig.publicAssets || [];
262
+ nitroConfig.publicAssets.push({ dir: resolve("./runtime/public"), maxAge: 31536e3 });
263
+ nitroConfig.virtual["#nuxt-og-image/browser"] = `export { createBrowser } from '${runtimeDir}/nitro/browsers/${isEdge ? "lambda" : "default"}'`;
264
+ nitroConfig.virtual["#nuxt-og-image/provider"] = `
265
+ import satori from '${runtimeDir}/nitro/providers/satori'
266
+ import browser from '${runtimeDir}/nitro/providers/browser'
267
+
268
+ export function useProvider(provider) {
269
+ if (provider === 'satori')
270
+ return satori
271
+ if (provider === 'browser')
272
+ return browser
273
+ }
274
+ `;
275
+ if (config.experimentalNitroBrowser) {
276
+ nitroConfig.virtual["#nuxt-og-image/providers/browser"] = `export * from '${runtimeDir}/nitro/providers/browser'`;
277
+ if (isEdge) {
278
+ ["puppeteer", "bufferutil", "utf-8-validate"].forEach((name) => {
279
+ nitroConfig.alias[name] = "unenv/runtime/mock/proxy";
280
+ });
281
+ }
153
282
  }
154
283
  });
155
284
  nuxt.hooks.hook("nitro:init", async (nitro) => {
156
- let entries = [];
157
- let cleanupEntries = [];
285
+ let screenshotQueue = [];
158
286
  const _routeRulesMatcher = toRouteMatcher(
159
287
  createRouter({ routes: nitro.options.routeRules })
160
288
  );
161
- const outputPath = join(nitro.options.output.publicDir, config.outputDir);
162
289
  nitro.hooks.hook("prerender:generate", async (ctx) => {
163
- if (ctx.route.includes(".") || ctx.route.endsWith(HtmlRendererRoute))
290
+ if (ctx.route.includes(".") || ctx.route.endsWith("__og_image__/html"))
164
291
  return;
165
- let html = ctx.contents;
292
+ const html = ctx.contents;
166
293
  if (!html)
167
294
  return;
168
- if (!html.includes(`id="${PayloadScriptId}"`))
169
- return;
295
+ const extractedPayload = extractOgPayload(html);
296
+ ctx.contents = html.replace(new RegExp(`<script id="${PayloadScriptId}" type="application/json">(.*?)<\/script>`), "");
170
297
  const routeRules = defu({}, ..._routeRulesMatcher.matchAll(ctx.route).reverse());
171
- if (routeRules.ogImage === false)
298
+ if (!extractedPayload || routeRules.ogImage === false)
172
299
  return;
173
- const screenshotPath = ctx._contents.match(new RegExp(`<link id="${LinkPrerenderId}" rel="prerender" href="(.*?)">`))?.[1];
174
- const fileName = `${hash({ route: ctx.route })}.png`;
175
- const absoluteUrl = withBase(`${config.outputDir}/${fileName}`, config.host);
176
- const entry = {
177
- fileName,
178
- absoluteUrl,
179
- outputPath: joinURL(nitro.options.output.publicDir, config.outputDir, fileName),
180
- linkingHtml: joinURL(nitro.options.output.publicDir, ctx.fileName),
181
- route: ctx.route,
182
- hasPayload: screenshotPath,
183
- routeRules: routeRules.ogImage || "",
184
- screenshotPath: screenshotPath || ctx.route
300
+ const payload = {
301
+ path: ctx.route,
302
+ ...extractedPayload,
303
+ ...routeRules.ogImage || {},
304
+ ctx
185
305
  };
186
- entries.push(entry);
187
- html = html.replace(MetaOgImageContentPlaceholder, entry.absoluteUrl);
188
- ctx.contents = html;
306
+ if ((nuxt.options._generate || payload.prerender) && payload.provider === "browser")
307
+ screenshotQueue.push(payload);
189
308
  });
190
309
  if (nuxt.options.dev)
191
310
  return;
192
- const outputOgImages = async () => {
193
- if (entries.length === 0)
311
+ const captureScreenshots = async () => {
312
+ if (screenshotQueue.length === 0)
194
313
  return;
195
- try {
196
- await mkdir(outputPath, { recursive: true });
197
- } catch (e) {
198
- }
199
314
  const previewProcess = execa("npx", ["serve", nitro.options.output.publicDir]);
200
315
  let browser = null;
201
316
  try {
@@ -209,25 +324,34 @@ declare module 'nitropack' {
209
324
  })).trim();
210
325
  browser = await createBrowser();
211
326
  if (browser) {
212
- nitro.logger.info(`Generating ${entries.length} og:images...`);
213
- for (const k in entries) {
214
- const entry = entries[k];
327
+ nitro.logger.info(`Pre-rendering ${screenshotQueue.length} og:image screenshots...`);
328
+ for (const k in screenshotQueue) {
329
+ const entry = screenshotQueue[k];
215
330
  const start = Date.now();
216
331
  let hasError = false;
332
+ const dirname = joinURL(nitro.options.output.publicDir, `${entry.ctx.fileName.replace("index.html", "")}__og_image__/`);
333
+ const filename = joinURL(dirname, "/og.png");
217
334
  try {
218
- const imgBuffer = await screenshot(browser, `${host}${entry.screenshotPath}`, config);
219
- await writeFile(entry.outputPath, imgBuffer);
335
+ const imgBuffer = await screenshot(browser, `${host}${entry.path}`, {
336
+ ...config,
337
+ ...entry
338
+ });
339
+ try {
340
+ await mkdir(dirname, { recursive: true });
341
+ } catch (e) {
342
+ }
343
+ await writeFile(filename, imgBuffer);
220
344
  } catch (e) {
221
345
  hasError = true;
222
346
  console.error(e);
223
347
  }
224
348
  const generateTimeMS = Date.now() - start;
225
349
  nitro.logger.log(chalk[hasError ? "red" : "gray"](
226
- ` ${Number(k) === entries.length - 1 ? "\u2514\u2500" : "\u251C\u2500"} /${config.outputDir}/${entry.fileName} (${generateTimeMS}ms) ${Math.round(Number(k) / (entries.length - 1) * 100)}%`
350
+ ` ${Number(k) === screenshotQueue.length - 1 ? "\u2514\u2500" : "\u251C\u2500"} ${relative(nitro.options.output.publicDir, filename)} (${generateTimeMS}ms) ${Math.round((Number(k) + 1) / screenshotQueue.length * 100)}%`
227
351
  ));
228
352
  }
229
353
  } else {
230
- nitro.logger.log(chalk.red("Failed to create browser to create og:images."));
354
+ nitro.logger.log(chalk.red("Failed to create a browser to create og:images."));
231
355
  }
232
356
  } catch (e) {
233
357
  console.error(e);
@@ -235,28 +359,13 @@ declare module 'nitropack' {
235
359
  await browser?.close();
236
360
  previewProcess.kill();
237
361
  }
238
- cleanupEntries = [...entries];
239
- entries = [];
362
+ screenshotQueue = [];
240
363
  };
241
364
  nitro.hooks.hook("rollup:before", async () => {
242
- await outputOgImages();
365
+ await captureScreenshots();
243
366
  });
244
367
  nitro.hooks.hook("close", async () => {
245
- await outputOgImages();
246
- for (const entry of cleanupEntries) {
247
- try {
248
- const html = await readFile(entry.linkingHtml, "utf-8");
249
- const newHtml = html.replace("__OG_IMAGE_SCREENSHOT_ALT", `Web page screenshot of ${entry.route}.`).replace(new RegExp(`<link id="${LinkPrerenderId}" rel="prerender" href="(.*?)">`), "").replace(new RegExp(`<script id="${PayloadScriptId}" type="application/json">(.*?)<\/script>`), "").replace("\n\n", "\n");
250
- if (html !== newHtml) {
251
- await writeFile(entry.linkingHtml, newHtml, { encoding: "utf-8" });
252
- }
253
- } catch (e) {
254
- console.error(e);
255
- }
256
- }
257
- const ogImageFolders = await fg([`**/${HtmlRendererRoute}`], { cwd: nitro.options.output.publicDir, onlyDirectories: true });
258
- for (const ogImageFolder of ogImageFolders)
259
- await rm(join(nitro.options.output.publicDir, ogImageFolder), { recursive: true, force: true });
368
+ await captureScreenshots();
260
369
  });
261
370
  });
262
371
  }
@@ -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
  }
@@ -0,0 +1,5 @@
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
+ }>;
5
+ export default _default;
@@ -0,0 +1,9 @@
1
+ import { defineComponent } from "vue";
2
+ import { defineOgImageDynamic } from "#imports";
3
+ export default defineComponent({
4
+ name: "OgImageDynamic",
5
+ setup(_, { attrs }) {
6
+ defineOgImageDynamic(attrs);
7
+ return () => null;
8
+ }
9
+ });
@@ -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
  });
@@ -0,0 +1,5 @@
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
+ }>;
5
+ export default _default;
@@ -1,9 +1,9 @@
1
1
  import { defineComponent } from "vue";
2
- import { defineOgImage } from "#imports";
2
+ import { defineOgImageStatic } from "#imports";
3
3
  export default defineComponent({
4
- name: "OgImage",
4
+ name: "OgImageStatic",
5
5
  setup(_, { attrs }) {
6
- defineOgImage(attrs);
6
+ defineOgImageStatic(attrs);
7
7
  return () => null;
8
8
  }
9
9
  });
@@ -7,89 +7,14 @@ const props = defineProps({
7
7
  </script>
8
8
 
9
9
  <template>
10
- <div class="wrap">
11
- <div class="bg1" />
12
- <div class="bg2" />
13
- <div>
14
- <p>This is the default og:image template from <a href="https://github.com/harlan-zw/nuxt-og-image" target="_blank">nuxt-og-image</a>.</p>
15
- <p>Create your own at <code>components/islands/OgImageTemplate.vue</code>.</p>
16
- </div>
17
- <div>
18
- <strong>Payload</strong>
19
- <code>
20
- <pre>{{ props }}</pre>
21
- </code>
10
+ <div :style="{ padding: '0 60px', width: '100%', height: '100%', backgroundColor: '#0c0c0c', backgroundImage: 'linear-gradient(to bottom, #dbf4ff, #fff1f1)', display: 'flex', alignItems: 'center' }">
11
+ <div :style="{ padding: '0 30px', display: 'flex', flexDirection: 'column' }">
12
+ <p :style="{ fontSize: '60px', fontWeight: 'bold', marginBottom: '20px' }">
13
+ {{ title }}
14
+ </p>
15
+ <p :style="{ fontSize: '26px' }">
16
+ {{ description }}
17
+ </p>
22
18
  </div>
23
19
  </div>
24
20
  </template>
25
-
26
- <style scoped>
27
- .wrap {
28
- width: 100%;
29
- height: 100%;
30
- display: flex;
31
- align-items: center;
32
- flex-direction: column;
33
- color: white;
34
- font-weight: bold;
35
- font-family: sans-serif;
36
- background-color: #0c0c0c;
37
- position: relative;
38
- }
39
-
40
- .bg1 {
41
- top: 0;
42
- left: 0;
43
- display: block;
44
- position: absolute;
45
- width: 100%;
46
- height: 100%;
47
- padding: 0 !important;
48
- margin: 0 !important;
49
- background-color: #0c0c0c;
50
- }
51
-
52
- .bg2 {
53
- top: 0;
54
- left: 0;
55
- z-index: 1;
56
- display: block;
57
- position: absolute;
58
- width: 100%;
59
- height: 100%;
60
- padding: 0 !important;
61
- margin: 0 !important;
62
- background: radial-gradient(at 100% 100%, #0f766e, rgba(12, 12, 12, 0.1) 60%);
63
- }
64
-
65
- a {
66
- color: inherit;
67
- padding-bottom: 3px;
68
- text-decoration: none;
69
- border-bottom: 3px solid #ff8235;
70
- }
71
-
72
- .wrap > div {
73
- z-index: 2;
74
- padding: 2rem;
75
- }
76
-
77
- code pre {
78
- background: #333;
79
- color: white;
80
- padding: 1rem;
81
- border-radius: 0.5rem;
82
- font-weight: lighter;
83
- font-size: 1.1rem;
84
- }
85
-
86
- p {
87
- font-size: 1.5em;
88
- font-weight: normal;
89
- }
90
-
91
- h1 {
92
- font-size: 4rem;
93
- margin: 0;
94
- }
95
- </style>
@@ -1,10 +1,5 @@
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;
3
+ export declare function defineOgImageDynamic(options?: OgImageScreenshotPayload): void;
4
+ export declare function defineOgImageStatic(options?: OgImageScreenshotPayload): void;
10
5
  export declare function defineOgImage(options?: OgImagePayload): void;