nuxt-og-image 2.0.0-beta.9 → 2.0.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.
Files changed (120) hide show
  1. package/README.md +18 -517
  2. package/dist/client/200.html +2 -2
  3. package/dist/client/404.html +2 -2
  4. package/dist/client/_nuxt/IconCSS.685477c5.js +1 -0
  5. package/dist/client/_nuxt/IconCSS.b41b9663.css +1 -0
  6. package/dist/client/_nuxt/ImageLoader.7571516f.css +1 -0
  7. package/dist/client/_nuxt/ImageLoader.fb4e5eb3.js +1 -0
  8. package/dist/client/_nuxt/entry.0fc037e0.js +143 -0
  9. package/dist/client/_nuxt/entry.1311cc29.css +1 -0
  10. package/dist/client/_nuxt/{error-404.02537f9e.js → error-404.068f19dd.js} +1 -1
  11. package/dist/client/_nuxt/error-404.f3dd5020.css +1 -0
  12. package/dist/client/_nuxt/error-500.06915589.css +1 -0
  13. package/dist/client/_nuxt/{error-500.a60bf0b5.js → error-500.4d72610e.js} +1 -1
  14. package/dist/client/_nuxt/index.33389497.js +1 -0
  15. package/dist/client/_nuxt/index.ffbea0a9.css +1 -0
  16. package/dist/client/_nuxt/options.e1a971ea.js +1 -0
  17. package/dist/client/_nuxt/png.110ab8f5.js +1 -0
  18. package/dist/client/_nuxt/{shiki.aace8ca2.js → shiki.3fe159de.js} +1 -1
  19. package/dist/client/_nuxt/svg.1a58cdf3.js +1 -0
  20. package/dist/client/_nuxt/vnodes.42fbc6e6.js +1 -0
  21. package/dist/client/index.html +2 -2
  22. package/dist/client/options/index.html +2 -2
  23. package/dist/client/png/index.html +2 -2
  24. package/dist/client/svg/index.html +2 -2
  25. package/dist/client/vnodes/index.html +2 -2
  26. package/dist/module.d.ts +117 -11
  27. package/dist/module.json +2 -2
  28. package/dist/module.mjs +391 -114
  29. package/dist/runtime/browserUtil.d.ts +1 -0
  30. package/dist/runtime/browserUtil.mjs +7 -5
  31. package/dist/runtime/components/{OgImageDynamic.d.ts → OgImage/Cached.d.ts} +2 -2
  32. package/dist/runtime/components/OgImage/Cached.mjs +10 -0
  33. package/dist/runtime/components/OgImage/Dynamic.d.ts +8 -0
  34. package/dist/runtime/components/{OgImageDynamic.mjs → OgImage/Dynamic.mjs} +3 -3
  35. package/dist/runtime/components/{OgImageScreenshot.d.ts → OgImage/Screenshot.d.ts} +2 -2
  36. package/dist/runtime/components/{OgImageScreenshot.mjs → OgImage/Screenshot.mjs} +2 -2
  37. package/dist/runtime/components/OgImage/Static.d.ts +8 -0
  38. package/dist/runtime/components/{OgImageStatic.mjs → OgImage/Static.mjs} +3 -3
  39. package/dist/runtime/components/{OgImageStatic.d.ts → OgImage/WithoutCache.d.ts} +2 -2
  40. package/dist/runtime/components/OgImage/WithoutCache.mjs +10 -0
  41. package/dist/runtime/components/OgImage/index.d.ts +5 -0
  42. package/dist/runtime/components/OgImage/index.mjs +10 -0
  43. package/dist/runtime/components/OgImageTemplate/Fallback.vue +156 -0
  44. package/dist/runtime/composables/defineOgImage.d.ts +12 -4
  45. package/dist/runtime/composables/defineOgImage.mjs +31 -49
  46. package/dist/runtime/composables/util.d.ts +2 -0
  47. package/dist/runtime/composables/util.mjs +26 -0
  48. package/dist/runtime/nitro/middleware/og.png.mjs +54 -8
  49. package/dist/runtime/nitro/plugins/prerender.d.ts +3 -0
  50. package/dist/runtime/nitro/plugins/prerender.mjs +28 -0
  51. package/dist/runtime/nitro/providers/browser/lambda.d.ts +1 -1
  52. package/dist/runtime/nitro/providers/browser/lambda.mjs +3 -3
  53. package/dist/runtime/nitro/providers/browser/{node.mjs → playwright.mjs} +0 -9
  54. package/dist/runtime/nitro/providers/browser/universal.d.ts +1 -0
  55. package/dist/runtime/nitro/providers/browser/universal.mjs +33 -0
  56. package/dist/runtime/nitro/providers/inline-css/mock.d.ts +5 -0
  57. package/dist/runtime/nitro/providers/inline-css/mock.mjs +3 -0
  58. package/dist/runtime/nitro/providers/inline-css/node.d.ts +5 -0
  59. package/dist/runtime/nitro/providers/inline-css/node.mjs +11 -0
  60. package/dist/runtime/nitro/providers/png/resvg-node.d.ts +4 -0
  61. package/dist/runtime/nitro/providers/png/resvg-node.mjs +6 -0
  62. package/dist/runtime/nitro/providers/png/resvg-wasm.d.ts +3 -0
  63. package/dist/runtime/nitro/providers/png/resvg-wasm.mjs +11 -0
  64. package/dist/runtime/nitro/providers/{svg2png/universal.d.ts → png/svg2png.d.ts} +2 -3
  65. package/dist/runtime/nitro/providers/png/svg2png.mjs +11 -0
  66. package/dist/runtime/nitro/providers/satori/{webworker.d.ts → yoga-wasm.d.ts} +2 -3
  67. package/dist/runtime/nitro/providers/satori/{webworker.mjs → yoga-wasm.mjs} +4 -5
  68. package/dist/runtime/nitro/renderers/browser.d.ts +2 -2
  69. package/dist/runtime/nitro/renderers/browser.mjs +14 -12
  70. package/dist/runtime/nitro/renderers/satori/index.d.ts +2 -2
  71. package/dist/runtime/nitro/renderers/satori/index.mjs +27 -32
  72. package/dist/runtime/nitro/renderers/satori/plugins/emojis.d.ts +1 -1
  73. package/dist/runtime/nitro/renderers/satori/plugins/emojis.mjs +19 -6
  74. package/dist/runtime/nitro/renderers/satori/plugins/encoding.d.ts +1 -1
  75. package/dist/runtime/nitro/renderers/satori/plugins/encoding.mjs +5 -7
  76. package/dist/runtime/nitro/renderers/satori/plugins/flex.d.ts +1 -1
  77. package/dist/runtime/nitro/renderers/satori/plugins/flex.mjs +8 -10
  78. package/dist/runtime/nitro/renderers/satori/plugins/imageSrc.d.ts +1 -1
  79. package/dist/runtime/nitro/renderers/satori/plugins/imageSrc.mjs +45 -13
  80. package/dist/runtime/nitro/renderers/satori/plugins/twClasses.d.ts +1 -1
  81. package/dist/runtime/nitro/renderers/satori/plugins/twClasses.mjs +5 -7
  82. package/dist/runtime/nitro/renderers/satori/utils.d.ts +4 -5
  83. package/dist/runtime/nitro/renderers/satori/utils.mjs +28 -17
  84. package/dist/runtime/nitro/routes/debug.d.ts +8 -0
  85. package/dist/runtime/nitro/routes/debug.mjs +14 -0
  86. package/dist/runtime/nitro/routes/font.mjs +2 -2
  87. package/dist/runtime/nitro/routes/html.mjs +102 -26
  88. package/dist/runtime/nitro/routes/options.d.ts +2 -2
  89. package/dist/runtime/nitro/routes/options.mjs +21 -20
  90. package/dist/runtime/nitro/routes/svg.mjs +2 -2
  91. package/dist/runtime/nitro/routes/vnode.mjs +2 -2
  92. package/dist/runtime/nitro/utils-pure.d.ts +0 -1
  93. package/dist/runtime/nitro/utils-pure.mjs +1 -4
  94. package/dist/runtime/nitro/utils.d.ts +11 -11
  95. package/dist/runtime/nitro/utils.mjs +67 -53
  96. package/dist/runtime/public-assets/__nuxt_og_image__/browser-provider-not-supported.png +0 -0
  97. package/dist/runtime/public-assets-optional/resvg/resvg.wasm +0 -0
  98. package/dist/types.d.ts +6 -0
  99. package/package.json +38 -27
  100. package/dist/client/_nuxt/IconCSS.ef0613e7.js +0 -1
  101. package/dist/client/_nuxt/ImageLoader.a4418cab.js +0 -1
  102. package/dist/client/_nuxt/entry.09f25aaf.css +0 -1
  103. package/dist/client/_nuxt/entry.fc9150b0.js +0 -5
  104. package/dist/client/_nuxt/error-404.1469f10f.css +0 -1
  105. package/dist/client/_nuxt/error-500.92b94fae.css +0 -1
  106. package/dist/client/_nuxt/error-component.8148b615.js +0 -3
  107. package/dist/client/_nuxt/index.80f38ec7.js +0 -1
  108. package/dist/client/_nuxt/options.cc3fd02b.js +0 -1
  109. package/dist/client/_nuxt/png.62758167.js +0 -1
  110. package/dist/client/_nuxt/svg.853cdaad.js +0 -1
  111. package/dist/client/_nuxt/vnodes.69b24963.js +0 -1
  112. package/dist/runtime/components/OgImageBasic.island.vue +0 -92
  113. package/dist/runtime/nitro/providers/svg2png/universal.mjs +0 -9
  114. /package/dist/runtime/nitro/providers/browser/{node.d.ts → playwright.d.ts} +0 -0
  115. /package/dist/runtime/nitro/providers/satori/{node.d.ts → default.d.ts} +0 -0
  116. /package/dist/runtime/nitro/providers/satori/{node.mjs → default.mjs} +0 -0
  117. /package/dist/runtime/{public-assets → public-assets-optional/inter-font}/inter-latin-ext-400-normal.woff +0 -0
  118. /package/dist/runtime/{public-assets → public-assets-optional/inter-font}/inter-latin-ext-700-normal.woff +0 -0
  119. /package/dist/runtime/{public-assets → public-assets-optional/svg2png}/svg2png.wasm +0 -0
  120. /package/dist/runtime/{public-assets → public-assets-optional/yoga}/yoga.wasm +0 -0
package/README.md CHANGED
@@ -10,17 +10,17 @@
10
10
 
11
11
 
12
12
  <p align="center">
13
- Enlightened OG Image generation for Nuxt 3.
13
+ Enlightened runtime images generated with Vue templates, for Nuxt.
14
14
  </p>
15
15
 
16
- <img src="https://repository-images.githubusercontent.com/578125755/05ce0b00-ef15-48d0-94b5-b999373a20f9">
16
+ <img src="https://repository-images.githubusercontent.com/578125755/90f77ca8-95be-4e06-9600-332afe1ba24f">
17
17
 
18
18
  <p align="center">
19
19
  <table>
20
20
  <tbody>
21
21
  <td align="center">
22
22
  <img width="800" height="0" /><br>
23
- <i>Status:</i> <a href="https://github.com/harlan-zw/nuxt-og-image/releases/tag/v1.0.0">v1 Released</a></b> <br>
23
+ <i>Status:</i> <a href="https://github.com/harlan-zw/nuxt-og-image/releases/tag/v2.0.0">v2 Released</a></b> <br>
24
24
  <sup> Please report any issues 🐛</sup><br>
25
25
  <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>
26
26
  <img width="800" height="0" />
@@ -29,7 +29,6 @@ Enlightened OG Image generation for Nuxt 3.
29
29
  </table>
30
30
  </p>
31
31
 
32
- ℹ️ Looking for a complete SEO solution? Check out [Nuxt SEO Kit](https://github.com/harlan-zw/nuxt-seo-kit).
33
32
 
34
33
  ## Features
35
34
 
@@ -38,529 +37,37 @@ Enlightened OG Image generation for Nuxt 3.
38
37
  - ▲ Render using [Satori](https://github.com/vercel/satori): Tailwind classes, Google fonts, emoji support and more!
39
38
  - 🤖 Or prerender using the Browser: Supporting painless, complex templates
40
39
  - 📸 Feeling lazy? Just generate screenshots for every page: hide elements, wait for animations, and more
41
- - ⚙️ Works on the edge: Vercel Edge and Cloudflare Workers
40
+ - ⚙️ Works on the edge: Vercel Edge, Netlify Edge and Cloudflare Workers
42
41
 
43
- ## Demos
42
+ 1. Install `nuxt-og-image` dependency to your project:
44
43
 
45
- - [Vercel Edge Demo](https://nuxt-og-image-playground.vercel.app/)
46
- - [StackBlitz - Minimal Playground Example](https://stackblitz.com/edit/nuxt-starter-pxs3wk?file=pages/index.vue)
47
- - [StackBlitz - Alpine Theme](https://stackblitz.com/edit/github-hgunsf?file=package.json)
48
-
49
- ## Install
50
44
 
51
45
  ```bash
52
- # Install module
53
- npm install --save-dev nuxt-og-image
54
- # Using yarn
55
- yarn add --dev nuxt-og-image
56
- ```
57
-
58
- ## Setup
59
-
60
- _nuxt.config.ts_
61
-
62
- ```ts
63
- export default defineNuxtConfig({
64
- modules: [
65
- 'nuxt-og-image',
66
- ],
67
- })
68
- ```
69
-
70
- #### Requirements
71
-
72
- This feature uses Nuxt Islands, which requires Nuxt >= 3.1.
73
-
74
- ### Add your host name
75
-
76
- The `og:image` meta tag requires the full URL, so you must provide your site host.
77
-
78
- _nuxt.config.ts_
79
-
80
- ```ts
81
- export default defineNuxtConfig({
82
- // Recommended
83
- runtimeConfig: {
84
- public: {
85
- siteUrl: process.env.NUXT_PUBLIC_SITE_URL || 'https://example.com',
86
- }
87
- },
88
- // OR
89
- ogImage: {
90
- host: 'https://example.com',
91
- },
92
- })
93
- ```
94
-
95
- # Guides
96
-
97
- ## Your first Satori `og:image`
98
-
99
- For this guide, you will create your Satori OG image using the default component for your home page.
100
-
101
- ### 1. Define a static OG Image
102
-
103
- Within your `pages/index.vue`, use `defineOgImageStatic` or `OgImageStatic` to define your `og:image` component.
104
-
105
- Make sure you have defined some metadata as props will be inferred from it.
106
-
107
- ```vue
108
- <script lang="ts" setup>
109
- // 1. make sure you have some meta
110
- useSeoMeta({
111
- title: 'Home',
112
- description: 'My awesome home page.',
113
- })
114
- // 2a. Use the Composition API
115
- defineOgImageStatic()
116
- </script>
117
-
118
- <template>
119
- <div>
120
- <!-- 2b. OR Component API -->
121
- <OgImageStatic />
122
- </div>
123
- </template>
124
- ```
125
-
126
- ### 2. View your `og:image`
127
-
128
- Appending `/__og_image__` to the end of the URL will show you the playground for that pages `og:image`. This provides
129
- a live preview of your `og:image` and allows you to edit it in real-time.
130
-
131
- For example, if your local site is hosted at `http://localhost:3000`, you can view your `og:image` at `http://localhost:3000/__og_image__`.
132
-
133
- ### 3. Customize your `og:image`
134
-
135
- While you have the playground open, start customising the OG Image by providing options to the `defineOgImageStatic` function.
136
-
137
- ```vue
138
- <script lang="ts" setup>
139
- defineOgImageStatic({
140
- title: 'Welcome to my site!',
141
- background: 'lightblue'
142
- })
143
- </script>
144
- ```
145
-
146
- Congrats, you've set up your first Satori `og:image`! You can checkout the [options](./src/runtime/components/OgImageBasic.island.vue) of the default template.
147
-
148
- ## Making your own Satori template
149
-
150
- Templates for OG images are powered by Nuxt Islands, which are just Vue components. In this guide we'll create a new
151
- template and use it for our `og:image`.
152
-
153
- ### 1. Create an island component
154
-
155
- Make a folder in your components directory called `islands`.
156
-
157
- Within this directory make a new component called `MyOgImage.vue`,
158
- you can use the following template to begin:
159
-
160
- ```vue
161
- <script setup lang="ts">
162
- const props = defineProps({
163
- title: String,
164
- })
165
- </script>
166
-
167
- <template>
168
- <div class="w-full h-full flex text-white bg-blue-500 items-center justify-center">
169
- <h1 :style="{ fontSize: '70px' }">
170
- {{ title }} 👋
171
- </h1>
172
- </div>
173
- </template>
174
- ```
175
-
176
- ### 2. Use the new template
177
-
178
- Now that you have your template, you can use it in for your `defineOgImageStatic` function.
179
-
180
- ```vue
181
- <script lang="ts" setup>
182
- defineOgImageStatic({
183
- component: 'MyOgImage',
184
- title: 'Welcome to my site!'
185
- })
186
- </script>
187
- ```
188
-
189
- View this image in your browser by appending `/__og_image__` to the end of the URL.
190
-
191
- ### 3. Customize your template
192
-
193
- Now that you have your template, you can start customizing it.
194
-
195
- Any options you pass to the `defineOgImageStatic` composable will be available in the component. With this in mind, we can
196
- add support for changing the background color.
197
-
198
- ```vue
199
- <script setup lang="ts">
200
- const props = defineProps({
201
- title: String,
202
- backgroundColor: String
203
- })
204
- </script>
205
-
206
- <template>
207
- <div :class="[backgroundColor]" class="w-full h-full flex text-white items-center justify-center">
208
- <h1 :style="{ fontSize: '70px' }">
209
- {{ title }} 👋
210
- </h1>
211
- </div>
212
- </template>
213
- ```
214
-
215
- Now let's customise the background to be green instead.
216
-
217
- ```vue
218
- <script lang="ts" setup>
219
- defineOgImageStatic({
220
- component: 'MyOgImage',
221
- title: 'Welcome to my site!',
222
- backgroundColor: 'bg-green-500'
223
- })
224
- </script>
225
- ```
226
-
227
- Within the playground, you should now see the background color change to green.
228
-
229
- ## Using Satori
230
-
231
- It's important to familiarize yourself with [Satori](https://github.com/vercel/satori) before you make more complex templates.
232
-
233
- Satori has limited capacity for rendering styles;
234
- you should reference which ones are available within their documentation.
235
-
236
- Out of the box, this module provides support for the following:
237
- - Tailwind classes (Note: Satori Tailwind support is experimental, not all classes are supported)
238
- - Google Fonts, default is Inter
239
- - Emoji support with [Twemoji](https://github.com/twitter/twemoji)
240
- - Relative image support (you should link images from your public directory `/my-image.png`)
241
-
242
- If you find Satori is too limiting for your needs, you can always use the `browser` provider to capture browser screenshots instead.
243
-
244
- ## Taking screenshots
245
-
246
- If you want to simply take a screenshot of your page, you can use the `OgImageScreenshot` component or `defineOgImageScreenshot` composable.
247
-
248
- ```vue
249
- <script lang="ts" setup>
250
- defineOgImageScreenshot()
251
- </script>
252
- ```
253
-
254
- Alternatively you can pass the `{ provider: 'browser' }` option to `defineOgImageStatic`.
255
-
256
- ```vue
257
- <script lang="ts" setup>
258
- defineOgImageStatic({
259
- component: 'MyAwesomeOgImage',
260
- // this will take a browser screenshot
261
- provider: 'browser'
262
- })
263
- </script>
264
- ```
265
-
266
- ### Requirements
267
-
268
- If you don't have a chromium binary installed on your system, run `npx playwright install`.
269
-
270
- If you are using this module in a CI context and the images aren't being generated,
271
- you may need to install a chromium binary.
272
-
273
- You can do this by running `npx playwright install` within your build command.
274
-
275
- _package.json_
276
-
277
- ```json
278
- {
279
- "scripts": {
280
- "build": "npx playwright install && nuxt build"
281
- }
282
- }
283
- ```
284
-
285
- # API
286
-
287
- The module exposes a composition and component API to implement your `og:image` generation. You should pick
288
- whichever one you prefer using.
289
-
290
- ## OgImageStatic / defineOgImageStatic
291
-
292
- The `OgImageStatic` component and the `defineOgImageStatic` composable creates a static image
293
- that will be pre-rendered.
294
-
295
- The options follow the [OgImageOptions](#OgImageOptions) interface,
296
- any additional options will be passed to the `component` as props.
297
-
298
- It is useful for images that do not change at runtime.
299
-
300
- ### Example
301
-
302
- ```vue
303
- <script setup lang="ts">
304
- // a. Composition API
305
- defineOgImageStatic({
306
- component: 'MyOgImageTemplate',
307
- title: 'Hello world',
308
- theme: 'dark'
309
- })
310
- </script>
311
-
312
- <template>
313
- <!-- b. Component API -->
314
- <OgImageStatic
315
- component="MyOgImageTemplate"
316
- title="Hello world"
317
- theme="dark"
318
- />
319
- </template>
320
- ```
321
-
322
-
323
- ## OgImageDynamic / defineOgImageDynamic
324
-
325
- The `OgImageDynamic` component and the `defineOgImageDynamic` composable creates a dynamic image. They are not pre-rendered and will
326
- be generated at runtime.
327
-
328
- The options follow the [OgImageOptions](#OgImageOptions) interface,
329
- any additional options will be passed to the `component` as props.
330
-
331
- This feature is not compatible with static sites built using `nuxi generate`.
332
-
333
- ### Example
334
-
335
- ```vue
336
- <script setup lang="ts">
337
- const dynamicData = await fetch('https://example.com/api')
338
-
339
- // a. Composition API
340
- defineOgImageDynamic({
341
- component: 'MyOgImageTemplate',
342
- title: 'Hello world',
343
- dynamicData,
344
- })
345
- </script>
346
-
347
- <template>
348
- <!-- b. Component API -->
349
- <OgImageDynamic
350
- component="MyOgImageTemplate"
351
- title="Hello world"
352
- :dynamic-data="dynamicData"
353
- />
354
- </template>
355
- ```
356
-
357
-
358
- ## OgImageOptions
359
-
360
- ### `alt`
361
-
362
- - Type: `string`
363
- - Default: `''`
364
- - Required: `false`
365
-
366
- The `og:image:alt` attribute for the image. It should describe the contents of the image.
367
-
368
- ### `height`
369
-
370
- - Type: `number`
371
- - Default: `630`
372
- - Required: `true`
373
-
374
- The height of the screenshot. Will be used to generate the `og:image:height` meta tag.
375
-
376
- ### `width`
377
-
378
- - Type: `number`
379
- - Default: `1200`
380
- - Required: `true`
381
-
382
- The width of the screenshot. Will be used to generate the `og:image:width` meta tag.
383
-
384
- ### `component`
385
-
386
- - Type: `string`
387
- - Default: `OgImageBasic`
388
- - Required: `true`
389
-
390
- The name of the component to use as the template. By default, it uses OgImageBasic provided by the module.
391
-
392
- ### `provider`
393
-
394
- - Type: `string`
395
- - Default: `satori`
396
- - Required: `false`
397
-
398
- The provider to use to generate the image. The default provider is `satori`.
399
- When you use `browser` it will use Puppeteer to generate the image.
400
-
401
- ### `prerender`
402
-
403
- - Type: `boolean`
404
- - Default: `true` when static, `false` when dynamic
405
-
406
-
407
- ## OgImageScreenshot / defineOgImageScreenshot
408
-
409
- The `OgImageScreenshot` component and the `defineOgImageScreenshot` composable creates a screenshot of a page using a browser.
410
-
411
- The options follow the [ScreenshotsOptions](#ScreenshotsOptions) interface.
412
-
413
-
414
- ### Example
415
-
416
- ```vue
417
- <script setup lang="ts">
418
- // a. Composition API
419
- defineOgImageScreenshot({
420
- // wait for animations
421
- delay: 1000,
422
- })
423
- </script>
424
-
425
- <template>
426
- <!-- b. Component API -->
427
- <OgImageScreenshot
428
- url="https://example.com"
429
- title="Hello world"
430
- theme="dark"
431
- />
432
- </template>
433
- ```
434
-
435
- ### ScreenshotsOptions
436
-
437
- This interface extends the [OgImageOptions](#OgImageOptions).
438
-
439
- #### `colorScheme`
440
-
441
- - Type: `'dark' | 'light'`
442
- - Default: `light`
443
- - Required: `false`
444
-
445
- The color scheme to use when generating the image. This is useful for generating dark mode images.
446
-
447
- ```ts
448
- defineOgImageScreenshot({
449
- colorScheme: 'dark'
450
- })
451
- ```
452
-
453
- #### `delay`
454
-
455
- - Type: `number`
456
- - Default: `0`
457
- - Required: `false`
458
-
459
- The delay to wait before taking the screenshot. This is useful if you want to wait for animations to complete.
460
-
461
- ```ts
462
- defineOgImageScreenshot({
463
- // wait 2 seconds
464
- delay: 2000
465
- })
46
+ #
47
+ yarn add -D nuxt-og-image
48
+ #
49
+ npm install -D nuxt-og-image
50
+ #
51
+ pnpm i -D nuxt-og-image
466
52
  ```
467
53
 
468
- #### `mask`
469
54
 
470
- - Type: `string`
471
- - Default: `undefined`
472
- - Required: `false`
473
-
474
- HTML selectors that should be removed from the image. Useful for removing popup banners or other elements that may be in the way.
475
-
476
- ```ts
477
- defineOgImageScreenshot({
478
- mask: '.popup-banner, .cookie-banner'
479
- })
480
- ```
481
-
482
- #### `selector`
483
-
484
- - Type: `string`
485
- - Default: `undefined`
486
- - Required: `false`
487
-
488
- The selector to take a screenshot of. This is useful if you want to exclude header / footer elements.
489
-
490
- ```ts
491
- defineOgImageScreenshot({
492
- selector: '.page-content'
493
- })
494
- ```
495
-
496
- ## Module Config
497
-
498
- ### `host`
499
-
500
- - Type: `string`
501
- - Default: `undefined`
502
- - Required: `true`
503
-
504
- The host of your site. This is required to generate the absolute path of the `og:image`.
505
-
506
- ### `defaults`
507
-
508
- - Type: `OgImageOptions`
509
- - Default: `{ component: 'OgImageBasic', width: 1200, height: 630, }`
510
- - Required: `false`
511
-
512
- The default options to use when generating images.
513
-
514
- ### `forcePrerender`
515
-
516
- - Type: `boolean`
517
- - Default: `false`
518
- - Required: `false`
519
-
520
- This is enabled when you run `nuxi generate`. It forces all OG images to be pre-rendered as the server is not available to generate
521
- runtime images.
522
-
523
- ### `fonts`
524
-
525
- - Type: ``${string}:${number}`[]`
526
- - Default: `['Inter:400', 'Inter:700']`
527
- - Required: `false`
528
-
529
- Fonts families to use when generating images with Satori. When not using Inter it will automatically fetch the font from Google Fonts.
530
-
531
- For example, if you wanted to add the Roboto font, you would add the following:
55
+ 2. Add it to your `modules` section in your `nuxt.config`:
532
56
 
533
57
  ```ts
534
58
  export default defineNuxtConfig({
535
- ogImage: {
536
- fonts: ['Roboto:400', 'Roboto:700']
537
- }
59
+ modules: ['nuxt-og-image']
538
60
  })
539
61
  ```
540
62
 
541
- ### `satoriOptions`
542
-
543
- - Type: `SatoriOptions`
544
- - Default: `{}`
545
- - Required: `false`
546
-
547
- Options to pass to Satori when generating images. See the [Satori docs](https://github.com/vercel/satori).
548
-
549
- ### `experimentalNitroBrowser` (experimental)
550
-
551
- - Type: `boolean`
552
- - Default: `false`
553
- - Required: `false`
63
+ ## Playgrounds
554
64
 
555
- In a server runtime, the default behaviour is to generate images using Satori. If you'd like to generate runtime images using the a browser instance
556
- for screenshots, you can enable this setting.
557
-
558
- This is experimental and may not work in all environments.
65
+ - [StackBlitz - Minimal Playground Example](https://stackblitz.com/edit/nuxt-starter-pxs3wk?file=pages/index.vue)
66
+ - [StackBlitz - Alpine Theme](https://stackblitz.com/edit/github-hgunsf?file=package.json)
559
67
 
560
- ## Examples
68
+ # Documentation
561
69
 
562
- - [Unhead Docs](https://github.com/unjs/unhead/tree/main/docs)
563
- - [harlanzw.com](https://github.com/harlan-zw/harlanzw.com)
70
+ [📖 Read the full documentation](https://nuxt-seo.netlify.app/og-image/getting-started/installation) for more information.
564
71
 
565
72
  ## Sponsors
566
73
 
@@ -570,12 +77,6 @@ This is experimental and may not work in all environments.
570
77
  </a>
571
78
  </p>
572
79
 
573
- ## Credits
574
-
575
- - Pooya Parsa [Kachick](https://github.com/unjs/kachik)
576
- - Anthony Fu (Nuxt Devtools)
577
- - Nuxt Team
578
-
579
80
  ## License
580
81
 
581
82
  MIT License © 2023-PRESENT [Harlan Wilton](https://github.com/harlan-zw)
@@ -1,7 +1,7 @@
1
1
  <!DOCTYPE html>
2
2
  <html >
3
3
  <head><meta charset="utf-8">
4
- <meta name="viewport" content="width=device-width, initial-scale=1"><link rel="modulepreload" as="script" crossorigin href="/__nuxt_og_image__/client/_nuxt/entry.fc9150b0.js"><link rel="preload" as="style" href="/__nuxt_og_image__/client/_nuxt/entry.09f25aaf.css"><link rel="prefetch" as="script" crossorigin href="/__nuxt_og_image__/client/_nuxt/error-component.8148b615.js"><link rel="stylesheet" href="/__nuxt_og_image__/client/_nuxt/entry.09f25aaf.css"><script>"use strict";const w=window,de=document.documentElement,knownColorSchemes=["dark","light"],preference=window.localStorage.getItem("nuxt-color-mode")||"system";let value=preference==="system"?getColorScheme():preference;const forcedColorMode=de.getAttribute("data-color-mode-forced");forcedColorMode&&(value=forcedColorMode),addColorScheme(value),w["__NUXT_COLOR_MODE__"]={preference,value,getColorScheme,addColorScheme,removeColorScheme};function addColorScheme(e){const o=""+e+"",t="";de.classList?de.classList.add(o):de.className+=" "+o,t&&de.setAttribute("data-"+t,e)}function removeColorScheme(e){const o=""+e+"",t="";de.classList?de.classList.remove(o):de.className=de.className.replace(new RegExp(o,"g"),""),t&&de.removeAttribute("data-"+t)}function prefersColorScheme(e){return w.matchMedia("(prefers-color-scheme"+e+")")}function getColorScheme(){if(w.matchMedia&&prefersColorScheme("").media!=="not all"){for(const e of knownColorSchemes)if(prefersColorScheme(":"+e).matches)return e}return"light"}
4
+ <meta name="viewport" content="width=device-width, initial-scale=1"><link rel="modulepreload" as="script" crossorigin href="/__nuxt_og_image__/client/_nuxt/entry.0fc037e0.js"><link rel="preload" as="style" href="/__nuxt_og_image__/client/_nuxt/entry.1311cc29.css"><link rel="prefetch" as="style" href="/__nuxt_og_image__/client/_nuxt/error-404.f3dd5020.css"><link rel="prefetch" as="script" crossorigin href="/__nuxt_og_image__/client/_nuxt/error-404.068f19dd.js"><link rel="prefetch" as="style" href="/__nuxt_og_image__/client/_nuxt/error-500.06915589.css"><link rel="prefetch" as="script" crossorigin href="/__nuxt_og_image__/client/_nuxt/error-500.4d72610e.js"><link rel="stylesheet" href="/__nuxt_og_image__/client/_nuxt/entry.1311cc29.css"><script>"use strict";(()=>{const a=window,e=document.documentElement,m=["dark","light"],c=window.localStorage.getItem("nuxt-color-mode")||"system";let n=c==="system"?f():c;const l=e.getAttribute("data-color-mode-forced");l&&(n=l),i(n),a["__NUXT_COLOR_MODE__"]={preference:c,value:n,getColorScheme:f,addColorScheme:i,removeColorScheme:d};function i(o){const t=""+o+"",s="";e.classList?e.classList.add(t):e.className+=" "+t,s&&e.setAttribute("data-"+s,o)}function d(o){const t=""+o+"",s="";e.classList?e.classList.remove(t):e.className=e.className.replace(new RegExp(t,"g"),""),s&&e.removeAttribute("data-"+s)}function r(o){return a.matchMedia("(prefers-color-scheme"+o+")")}function f(){if(a.matchMedia&&r("").media!=="not all"){for(const o of m)if(r(":"+o).matches)return o}return"light"}})();
5
5
  </script></head>
6
- <body ><div id="__nuxt"></div><script>window.__NUXT__={serverRendered:false,config:{public:{},app:{baseURL:"\u002F__nuxt_og_image__\u002Fclient",buildAssetsDir:"\u002F_nuxt\u002F",cdnURL:""}},data:{},state:{}}</script><script type="module" src="/__nuxt_og_image__/client/_nuxt/entry.fc9150b0.js" crossorigin></script></body>
6
+ <body ><div id="__nuxt"><svg class="nuxt-spa-loading" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 37 25" fill="none" width="80"><path d="M24.236 22.006h10.742L25.563 5.822l-8.979 14.31a4 4 0 0 1-3.388 1.874H2.978l11.631-20 5.897 10.567"></path></svg><style>.nuxt-spa-loading{position:fixed;top:50%;left:50%;transform:translate(-50%, -50%)}.nuxt-spa-loading>path{fill:none;stroke:#00DC82;stroke-width:4px;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:128;stroke-dashoffset:128;animation:nuxt-spa-loading-move 3s linear infinite}@keyframes nuxt-spa-loading-move{100%{stroke-dashoffset:-128}}</style></div><script type="application/json" id="__NUXT_DATA__" data-ssr="false">[{"_errors":1,"serverRendered":2,"data":3,"state":4},{},false,{},{}]</script><script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__nuxt_og_image__/client",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script><script type="module" src="/__nuxt_og_image__/client/_nuxt/entry.0fc037e0.js" crossorigin></script></body>
7
7
  </html>
@@ -1,7 +1,7 @@
1
1
  <!DOCTYPE html>
2
2
  <html >
3
3
  <head><meta charset="utf-8">
4
- <meta name="viewport" content="width=device-width, initial-scale=1"><link rel="modulepreload" as="script" crossorigin href="/__nuxt_og_image__/client/_nuxt/entry.fc9150b0.js"><link rel="preload" as="style" href="/__nuxt_og_image__/client/_nuxt/entry.09f25aaf.css"><link rel="prefetch" as="script" crossorigin href="/__nuxt_og_image__/client/_nuxt/error-component.8148b615.js"><link rel="stylesheet" href="/__nuxt_og_image__/client/_nuxt/entry.09f25aaf.css"><script>"use strict";const w=window,de=document.documentElement,knownColorSchemes=["dark","light"],preference=window.localStorage.getItem("nuxt-color-mode")||"system";let value=preference==="system"?getColorScheme():preference;const forcedColorMode=de.getAttribute("data-color-mode-forced");forcedColorMode&&(value=forcedColorMode),addColorScheme(value),w["__NUXT_COLOR_MODE__"]={preference,value,getColorScheme,addColorScheme,removeColorScheme};function addColorScheme(e){const o=""+e+"",t="";de.classList?de.classList.add(o):de.className+=" "+o,t&&de.setAttribute("data-"+t,e)}function removeColorScheme(e){const o=""+e+"",t="";de.classList?de.classList.remove(o):de.className=de.className.replace(new RegExp(o,"g"),""),t&&de.removeAttribute("data-"+t)}function prefersColorScheme(e){return w.matchMedia("(prefers-color-scheme"+e+")")}function getColorScheme(){if(w.matchMedia&&prefersColorScheme("").media!=="not all"){for(const e of knownColorSchemes)if(prefersColorScheme(":"+e).matches)return e}return"light"}
4
+ <meta name="viewport" content="width=device-width, initial-scale=1"><link rel="modulepreload" as="script" crossorigin href="/__nuxt_og_image__/client/_nuxt/entry.0fc037e0.js"><link rel="preload" as="style" href="/__nuxt_og_image__/client/_nuxt/entry.1311cc29.css"><link rel="prefetch" as="style" href="/__nuxt_og_image__/client/_nuxt/error-404.f3dd5020.css"><link rel="prefetch" as="script" crossorigin href="/__nuxt_og_image__/client/_nuxt/error-404.068f19dd.js"><link rel="prefetch" as="style" href="/__nuxt_og_image__/client/_nuxt/error-500.06915589.css"><link rel="prefetch" as="script" crossorigin href="/__nuxt_og_image__/client/_nuxt/error-500.4d72610e.js"><link rel="stylesheet" href="/__nuxt_og_image__/client/_nuxt/entry.1311cc29.css"><script>"use strict";(()=>{const a=window,e=document.documentElement,m=["dark","light"],c=window.localStorage.getItem("nuxt-color-mode")||"system";let n=c==="system"?f():c;const l=e.getAttribute("data-color-mode-forced");l&&(n=l),i(n),a["__NUXT_COLOR_MODE__"]={preference:c,value:n,getColorScheme:f,addColorScheme:i,removeColorScheme:d};function i(o){const t=""+o+"",s="";e.classList?e.classList.add(t):e.className+=" "+t,s&&e.setAttribute("data-"+s,o)}function d(o){const t=""+o+"",s="";e.classList?e.classList.remove(t):e.className=e.className.replace(new RegExp(t,"g"),""),s&&e.removeAttribute("data-"+s)}function r(o){return a.matchMedia("(prefers-color-scheme"+o+")")}function f(){if(a.matchMedia&&r("").media!=="not all"){for(const o of m)if(r(":"+o).matches)return o}return"light"}})();
5
5
  </script></head>
6
- <body ><div id="__nuxt"></div><script>window.__NUXT__={serverRendered:false,config:{public:{},app:{baseURL:"\u002F__nuxt_og_image__\u002Fclient",buildAssetsDir:"\u002F_nuxt\u002F",cdnURL:""}},data:{},state:{}}</script><script type="module" src="/__nuxt_og_image__/client/_nuxt/entry.fc9150b0.js" crossorigin></script></body>
6
+ <body ><div id="__nuxt"><svg class="nuxt-spa-loading" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 37 25" fill="none" width="80"><path d="M24.236 22.006h10.742L25.563 5.822l-8.979 14.31a4 4 0 0 1-3.388 1.874H2.978l11.631-20 5.897 10.567"></path></svg><style>.nuxt-spa-loading{position:fixed;top:50%;left:50%;transform:translate(-50%, -50%)}.nuxt-spa-loading>path{fill:none;stroke:#00DC82;stroke-width:4px;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:128;stroke-dashoffset:128;animation:nuxt-spa-loading-move 3s linear infinite}@keyframes nuxt-spa-loading-move{100%{stroke-dashoffset:-128}}</style></div><script type="application/json" id="__NUXT_DATA__" data-ssr="false">[{"_errors":1,"serverRendered":2,"data":3,"state":4},{},false,{},{}]</script><script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__nuxt_og_image__/client",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script><script type="module" src="/__nuxt_og_image__/client/_nuxt/entry.0fc037e0.js" crossorigin></script></body>
7
7
  </html>
@@ -0,0 +1 @@
1
+ import{g as r,H as u,I as p,n as t,o as l,c as _,s as f,_ as m}from"./entry.0fc037e0.js";const d=r({__name:"IconCSS",props:{name:{type:String,required:!0},size:{type:String,default:""}},setup(a){const s=a;u(e=>({"193e663e":i.value}));const n=p();n?.nuxtIcon?.aliases;const c=t(()=>(n?.nuxtIcon?.aliases||{})[s.name]||s.name),i=t(()=>`url('https://api.iconify.design/${c.value.replace(":","/")}.svg')`),o=t(()=>{if(!s.size&&typeof n.nuxtIcon?.size=="boolean"&&!n.nuxtIcon?.size)return;const e=s.size||n.nuxtIcon?.size||"1em";return String(Number(e))===e?`${e}px`:e});return(e,x)=>(l(),_("span",{style:f({width:o.value,height:o.value})},null,4))}});const g=m(d,[["__scopeId","data-v-1172c8f8"]]);export{g as default};
@@ -0,0 +1 @@
1
+ span[data-v-1172c8f8]{background-color:currentColor;display:inline-block;-webkit-mask-image:var(--193e663e);mask-image:var(--193e663e);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;vertical-align:middle}
@@ -0,0 +1 @@
1
+ img[data-v-23ec6856]{height:auto!important;margin:0 auto;max-width:100%;transition:.4s ease-in-out;width:auto!important}
@@ -0,0 +1 @@
1
+ import{g as p,r as c,k as m,l as r,n as u,q as d,o as g,c as f,s as y,_ as v}from"./entry.0fc037e0.js";const x=p({__name:"ImageLoader",props:{src:String,aspectRatio:Number,description:String},setup(a){const s=a,n=c(),o=c(0);function i(e){const t=n.value,_=Date.now();t.src="",o.value=0,t.style.opacity="0",t.onload=()=>{t.style.opacity="1",o.value=Date.now()-_},t.src=e}m(()=>{r(()=>s.src,e=>{i(e)},{immediate:!0})});const l=u(()=>s.description.replace("%s",o.value.toString()));return r(l,e=>{d.value=e}),(e,t)=>(g(),f("img",{ref_key:"image",ref:n,class:"max-h-full border-1 border-light-500 rounded",style:y({aspectRatio:a.aspectRatio})},null,4))}});const S=v(x,[["__scopeId","data-v-23ec6856"]]);export{S as _};