nuxt-og-image 2.0.0-beta.5 → 2.0.0-beta.50

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 (95) hide show
  1. package/README.md +265 -53
  2. package/dist/client/200.html +2 -2
  3. package/dist/client/404.html +2 -2
  4. package/dist/client/_nuxt/IconCSS.73da91e8.js +1 -0
  5. package/dist/client/_nuxt/IconCSS.8bbd2aa2.css +1 -0
  6. package/dist/client/_nuxt/ImageLoader.1dc2da65.js +1 -0
  7. package/dist/client/_nuxt/ImageLoader.7571516f.css +1 -0
  8. package/dist/client/_nuxt/entry.9627f7dd.js +5 -0
  9. package/dist/client/_nuxt/entry.f4586a2b.css +1 -0
  10. package/dist/client/_nuxt/{error-404.1ff52902.js → error-404.e8b1a738.js} +1 -1
  11. package/dist/client/_nuxt/{error-500.f7d30da5.js → error-500.34be4bd8.js} +1 -1
  12. package/dist/client/_nuxt/error-component.4733114a.js +3 -0
  13. package/dist/client/_nuxt/index.35b0e13d.js +1 -0
  14. package/dist/client/_nuxt/index.403133d8.css +1 -0
  15. package/dist/client/_nuxt/{options.56a3e5f9.js → options.bd244bf2.js} +1 -1
  16. package/dist/client/_nuxt/{png.37f3e77b.js → png.765461fb.js} +1 -1
  17. package/dist/client/_nuxt/{shiki.3a930bb8.js → shiki.474ce6f4.js} +1 -1
  18. package/dist/client/_nuxt/{svg.186c6bd1.js → svg.1511e50d.js} +1 -1
  19. package/dist/client/_nuxt/{vnodes.a799f183.js → vnodes.4f695971.js} +1 -1
  20. package/dist/client/index.html +2 -2
  21. package/dist/client/options/index.html +2 -2
  22. package/dist/client/png/index.html +2 -2
  23. package/dist/client/svg/index.html +2 -2
  24. package/dist/client/vnodes/index.html +2 -2
  25. package/dist/module.d.ts +22 -7
  26. package/dist/module.json +1 -1
  27. package/dist/module.mjs +312 -114
  28. package/dist/runtime/browserUtil.d.ts +1 -0
  29. package/dist/runtime/browserUtil.mjs +10 -5
  30. package/dist/runtime/components/OgImageBasic.island.vue +5 -0
  31. package/dist/runtime/components/OgImageDynamic.d.ts +1 -1
  32. package/dist/runtime/components/OgImageScreenshot.d.ts +1 -1
  33. package/dist/runtime/components/OgImageStatic.d.ts +1 -1
  34. package/dist/runtime/composables/defineOgImage.mjs +15 -12
  35. package/dist/runtime/nitro/middleware/og.png.mjs +51 -7
  36. package/dist/runtime/nitro/middleware/playground.mjs +4 -3
  37. package/dist/runtime/nitro/plugins/prerender.d.ts +3 -0
  38. package/dist/runtime/nitro/plugins/prerender.mjs +26 -0
  39. package/dist/runtime/nitro/providers/browser/lambda.d.ts +1 -1
  40. package/dist/runtime/nitro/providers/browser/lambda.mjs +3 -3
  41. package/dist/runtime/nitro/providers/browser/{node.mjs → playwright.mjs} +0 -9
  42. package/dist/runtime/nitro/providers/browser/universal.d.ts +1 -0
  43. package/dist/runtime/nitro/providers/browser/universal.mjs +33 -0
  44. package/dist/runtime/nitro/providers/png/resvg-node.d.ts +5 -0
  45. package/dist/runtime/nitro/providers/png/resvg-node.mjs +6 -0
  46. package/dist/runtime/nitro/providers/png/resvg-wasm.d.ts +4 -0
  47. package/dist/runtime/nitro/providers/png/resvg-wasm.mjs +11 -0
  48. package/dist/runtime/nitro/providers/png/svg2png.mjs +11 -0
  49. package/dist/runtime/nitro/providers/satori/{webworker.mjs → yoga-wasm.mjs} +4 -5
  50. package/dist/runtime/nitro/renderers/browser.d.ts +2 -2
  51. package/dist/runtime/nitro/renderers/browser.mjs +14 -7
  52. package/dist/runtime/nitro/renderers/satori/index.d.ts +2 -2
  53. package/dist/runtime/nitro/renderers/satori/index.mjs +15 -16
  54. package/dist/runtime/nitro/renderers/satori/plugins/emojis.d.ts +1 -1
  55. package/dist/runtime/nitro/renderers/satori/plugins/emojis.mjs +24 -9
  56. package/dist/runtime/nitro/renderers/satori/plugins/encoding.d.ts +1 -1
  57. package/dist/runtime/nitro/renderers/satori/plugins/encoding.mjs +2 -1
  58. package/dist/runtime/nitro/renderers/satori/plugins/flex.d.ts +1 -1
  59. package/dist/runtime/nitro/renderers/satori/plugins/imageSrc.d.ts +1 -1
  60. package/dist/runtime/nitro/renderers/satori/plugins/imageSrc.mjs +25 -3
  61. package/dist/runtime/nitro/renderers/satori/plugins/twClasses.d.ts +1 -1
  62. package/dist/runtime/nitro/renderers/satori/utils.d.ts +4 -4
  63. package/dist/runtime/nitro/renderers/satori/utils.mjs +26 -13
  64. package/dist/runtime/nitro/routes/debug.d.ts +4 -0
  65. package/dist/runtime/nitro/routes/debug.mjs +9 -0
  66. package/dist/runtime/nitro/routes/html.mjs +100 -25
  67. package/dist/runtime/nitro/routes/options.mjs +20 -22
  68. package/dist/runtime/nitro/routes/svg.mjs +3 -1
  69. package/dist/runtime/nitro/routes/vnode.mjs +3 -1
  70. package/dist/runtime/nitro/util-hostname.d.ts +2 -0
  71. package/dist/runtime/nitro/util-hostname.mjs +20 -0
  72. package/dist/runtime/nitro/utils-pure.d.ts +3 -2
  73. package/dist/runtime/nitro/utils-pure.mjs +9 -8
  74. package/dist/runtime/nitro/utils.d.ts +6 -8
  75. package/dist/runtime/nitro/utils.mjs +50 -47
  76. package/dist/runtime/public-assets/__nuxt_og_image__/browser-provider-not-supported.png +0 -0
  77. package/dist/runtime/public-assets-optional/resvg/resvg.wasm +0 -0
  78. package/dist/types.d.ts +6 -0
  79. package/package.json +37 -24
  80. package/dist/client/_nuxt/IconCSS.a041aca0.js +0 -1
  81. package/dist/client/_nuxt/ImageLoader.9bf39d71.js +0 -1
  82. package/dist/client/_nuxt/entry.74018bda.js +0 -5
  83. package/dist/client/_nuxt/entry.7a8c1ab2.css +0 -1
  84. package/dist/client/_nuxt/error-component.cf7543e5.js +0 -3
  85. package/dist/client/_nuxt/index.3f356409.js +0 -1
  86. package/dist/runtime/nitro/providers/svg2png/universal.mjs +0 -9
  87. /package/dist/runtime/nitro/providers/browser/{node.d.ts → playwright.d.ts} +0 -0
  88. /package/dist/runtime/nitro/providers/{svg2png/universal.d.ts → png/svg2png.d.ts} +0 -0
  89. /package/dist/runtime/nitro/providers/satori/{node.d.ts → default.d.ts} +0 -0
  90. /package/dist/runtime/nitro/providers/satori/{node.mjs → default.mjs} +0 -0
  91. /package/dist/runtime/nitro/providers/satori/{webworker.d.ts → yoga-wasm.d.ts} +0 -0
  92. /package/dist/runtime/{public-assets → public-assets-optional/inter-font}/inter-latin-ext-400-normal.woff +0 -0
  93. /package/dist/runtime/{public-assets → public-assets-optional/inter-font}/inter-latin-ext-700-normal.woff +0 -0
  94. /package/dist/runtime/{public-assets → public-assets-optional/svg2png}/svg2png.wasm +0 -0
  95. /package/dist/runtime/{public-assets → public-assets-optional/yoga}/yoga.wasm +0 -0
package/README.md CHANGED
@@ -13,7 +13,7 @@
13
13
  Enlightened OG Image generation for Nuxt 3.
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>
@@ -38,7 +38,7 @@ Enlightened OG Image generation for Nuxt 3.
38
38
  - ▲ Render using [Satori](https://github.com/vercel/satori): Tailwind classes, Google fonts, emoji support and more!
39
39
  - 🤖 Or prerender using the Browser: Supporting painless, complex templates
40
40
  - 📸 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
41
+ - ⚙️ Works on the edge: Vercel Edge, Netlify Edge and Cloudflare Workers
42
42
 
43
43
  ## Demos
44
44
 
@@ -46,13 +46,33 @@ Enlightened OG Image generation for Nuxt 3.
46
46
  - [StackBlitz - Minimal Playground Example](https://stackblitz.com/edit/nuxt-starter-pxs3wk?file=pages/index.vue)
47
47
  - [StackBlitz - Alpine Theme](https://stackblitz.com/edit/github-hgunsf?file=package.json)
48
48
 
49
+ ## Runtime Provider Compatibility
50
+
51
+ Both Satori and Browser will work in Node based environments. Prerendering is fully supported.
52
+
53
+ When you want to generate dynamic images at runtime there are certain Nitro runtime limitations.
54
+
55
+ | Provider | Satori | Browser |
56
+ |---------------------------------------------------------------------------------|-----------------------|---------|
57
+ | Node | ✅ | ✅ |
58
+ | [Vercel](https://nuxt-og-image-playground.vercel.app/) | ✅ | ❌ |
59
+ | [Vercel Edge](https://nuxt-og-image-playground-gkdt.vercel.app/) | ✅ | ❌ |
60
+ | [Cloudflare Pages](https://nuxt-og-image-playground.pages.dev/) | ✅ | ❌ |
61
+ | [Netlify](https://nuxt-og-image-playground-netlify.netlify.app/) | ✅ | ❌ |
62
+ | [Netlify Edge](https://nuxt-og-image-playground-netlify-edge.netlify.app/) | (Soon) | ❌ |
63
+ | [StackBlitz](https://stackblitz.com/edit/nuxt-starter-pxs3wk?file=package.json) | ✅ (emojis don't work) | ❌ |
64
+
65
+ Other providers are yet to be tested. Please create an issue if your nitro preset is not listed.
66
+
49
67
  ## Install
50
68
 
69
+ Note: The `main` branch is documentation for the beta version, it's recommended to use this version.
70
+
51
71
  ```bash
52
72
  # Install module
53
- npm install --save-dev nuxt-og-image
73
+ npm install --save-dev nuxt-og-image@beta
54
74
  # Using yarn
55
- yarn add --dev nuxt-og-image
75
+ yarn add --dev nuxt-og-image@beta
56
76
  ```
57
77
 
58
78
  ## Setup
@@ -67,30 +87,8 @@ export default defineNuxtConfig({
67
87
  })
68
88
  ```
69
89
 
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
- ```
90
+ This module requires [Nuxt Server Components](https://nuxt.com/docs/guide/directory-structure/components#standalone-server-components)
91
+ which will be enabled for you.
94
92
 
95
93
  # Guides
96
94
 
@@ -162,15 +160,25 @@ you can use the following template to begin:
162
160
  const props = defineProps({
163
161
  title: String,
164
162
  })
163
+
164
+ // inherited attrs can mess up the satori parser
165
+ defineOptions({
166
+ inheritAttrs: false,
167
+ })
165
168
  </script>
166
169
 
167
170
  <template>
168
171
  <div class="w-full h-full flex text-white bg-blue-500 items-center justify-center">
169
- <h1 :style="{ fontSize: '70px' }">
172
+ <h1>
170
173
  {{ title }} 👋
171
174
  </h1>
172
175
  </div>
173
176
  </template>
177
+ <style scoped>
178
+ h1 {
179
+ font-size: 70px;
180
+ }
181
+ </style>
174
182
  ```
175
183
 
176
184
  ### 2. Use the new template
@@ -205,14 +213,19 @@ const props = defineProps({
205
213
 
206
214
  <template>
207
215
  <div :class="[backgroundColor]" class="w-full h-full flex text-white items-center justify-center">
208
- <h1 :style="{ fontSize: '70px' }">
216
+ <h1>
209
217
  {{ title }} 👋
210
218
  </h1>
211
219
  </div>
212
220
  </template>
221
+ <style scoped>
222
+ h1 {
223
+ font-size: 70px;
224
+ }
225
+ </style>
213
226
  ```
214
227
 
215
- Now let's customise the background to be green instead.
228
+ Now let's customize the background to be green instead.
216
229
 
217
230
  ```vue
218
231
  <script lang="ts" setup>
@@ -241,6 +254,78 @@ Out of the box, this module provides support for the following:
241
254
 
242
255
  If you find Satori is too limiting for your needs, you can always use the `browser` provider to capture browser screenshots instead.
243
256
 
257
+ ## SSG Images
258
+
259
+ When using `nuxt generate`, you will need to provide some additional configuration.
260
+
261
+ - You must provide a `siteUrl` so that the meta tags can be generated correctly as absolute URLs.
262
+
263
+ ```ts
264
+ export default defineNuxtConfig({
265
+ // Recommended
266
+ runtimeConfig: {
267
+ public: {
268
+ siteUrl: process.env.NUXT_PUBLIC_SITE_URL || 'https://example.com',
269
+ }
270
+ },
271
+ // OR
272
+ ogImage: {
273
+ host: 'https://example.com',
274
+ },
275
+ })
276
+ ```
277
+
278
+ - You must prerender all pages that use `og:image`.
279
+
280
+ ```ts
281
+ export default defineNuxtConfig({
282
+ nitro: {
283
+ prerender: {
284
+ crawlLinks: true, // recommended
285
+ routes: [
286
+ '/',
287
+ // list all routes that use og:image if you're not using crawlLinks
288
+ '/about',
289
+ '/blog',
290
+ '/blog/my-first-post',
291
+ ]
292
+ }
293
+ }
294
+ })
295
+ ```
296
+
297
+ ## SSR Images
298
+
299
+ When using `nuxt build`, you can only use the `browser` provider with the `node` Nitro preset.
300
+
301
+ If you intend to use the `browser` provider in production, make sure you include the `playwright` dependency.
302
+
303
+ ```bash
304
+ npm i playwright
305
+ ```
306
+
307
+ You can get around this by prerendering any pages that use `og:image`. Note that dynamic browser generated images are not supported at all,
308
+ you should use the Satori provider.
309
+
310
+
311
+ ```ts
312
+ export default defineNuxtConfig({
313
+ nitro: {
314
+ prerender: {
315
+ crawlLinks: true, // recommended
316
+ routes: [
317
+ '/',
318
+ // list all routes that use og:image if you're not using crawlLinks
319
+ '/about',
320
+ '/blog',
321
+ '/blog/my-first-post',
322
+ ]
323
+ }
324
+ }
325
+ })
326
+ ```
327
+
328
+
244
329
  ## Taking screenshots
245
330
 
246
331
  If you want to simply take a screenshot of your page, you can use the `OgImageScreenshot` component or `defineOgImageScreenshot` composable.
@@ -282,6 +367,135 @@ _package.json_
282
367
  }
283
368
  ```
284
369
 
370
+ ## Custom Fonts / Supporting non-english characters
371
+
372
+ When creating your OG Image, you'll probably want to use a font custom to your project.
373
+
374
+ To make this easier for you, Google Fonts are loaded by default with Inter 400 and Inter 700.
375
+
376
+ You can easily load different Google Fonts by using their name+weight. For example:
377
+
378
+ ```ts
379
+ export default defineNuxtConfig({
380
+ ogImage: {
381
+ fonts: [
382
+ // will load the Noto Sans font from Google fonts
383
+ 'Noto+Sans:400'
384
+ ]
385
+ }
386
+ })
387
+ ```
388
+
389
+ This also lets you support non-english characters by adding the appropriate font to your config.
390
+
391
+ For example, to support Hebrew characters, you can use the config:
392
+
393
+ ```ts
394
+ export default defineNuxtConfig({
395
+ ogImage: {
396
+ fonts: [
397
+ // will load this font from Google fonts
398
+ 'Noto+Sans+Hebrew:400'
399
+ ]
400
+ }
401
+ })
402
+ ````
403
+
404
+ If you'd like to load a font locally,
405
+ then you can provide the configuration as an object:
406
+
407
+ ```ts
408
+ export default defineNuxtConfig({
409
+ ogImage: {
410
+ fonts: [
411
+ {
412
+ name: 'optieinstein',
413
+ weight: 800,
414
+ // path must point to a public font file
415
+ path: '/OPTIEinstein-Black.otf',
416
+ }
417
+ ],
418
+ }
419
+ })
420
+ ```
421
+
422
+ Make sure to set the font family in your component to match the font name.
423
+
424
+ ```vue
425
+ <template>
426
+ <div :style="{ fontFamily: 'optieinstein' }">
427
+ <!-- Your component -->
428
+ </div>
429
+ </template>
430
+ ```
431
+
432
+ ## Runtime Caching
433
+
434
+ When images are generated at runtime, caching is enabled by default to reduce the load on your server.
435
+
436
+ By default, it will use the default storage engine for your Nitro preset.
437
+ You can customise the storage engine by providing a `runtimeCacheStorage` option to the `ogImage` config.
438
+
439
+ The option takes the same configuration as the Nuxt `nitro.storage` option.
440
+ See the [Nitro Storage Layer](https://nitro.unjs.io/guide/storage) documentation for more details.
441
+
442
+ For example:
443
+
444
+ ```ts
445
+ export default defineNuxtConfig({
446
+ ogImage: {
447
+ // cloudflare kv binding example, set your own config
448
+ runtimeCacheStorage: {
449
+ driver: 'cloudflare-kv-binding',
450
+ binding: 'OG_IMAGE_CACHE'
451
+ }
452
+ }
453
+ })
454
+ ````
455
+
456
+ By default, static images will be cached for 24 hours. You can change the image TTL by providing `cacheTtl` when defining the image.
457
+
458
+ ```ts
459
+ defineOgImageStatic({
460
+ // ...
461
+ cacheTtl: 60 * 60 * 24 * 7 // 7 days
462
+ })
463
+ ```
464
+
465
+ Alternatively, you can change the default cacheTtl time in your nuxt.config.
466
+
467
+
468
+ ```ts
469
+ export default defineNuxtConfig({
470
+ ogImage: {
471
+ defaults: {
472
+ cacheTtl: 60 * 60 * 24 * 7 // 7 days
473
+ }
474
+ }
475
+ })
476
+ ````
477
+
478
+ You can also provide a configuration for the `cacheKey`. This gives you control over the cache bursting of the images.
479
+
480
+ ```vue
481
+ <script lang="ts" setup>
482
+ defineOgImageStatic({
483
+ cacheKey: `${myData.id}:${myData.updatedAt}`,
484
+ })
485
+ </script>
486
+ ```
487
+
488
+ If you prefer not to cache your images you can always disable them by providing a `false` value.
489
+
490
+ ```ts
491
+ export default defineNuxtConfig({
492
+ ogImage: {
493
+ // no runtime cache
494
+ runtimeCacheStorage: false
495
+ }
496
+ })
497
+ ````
498
+
285
499
  # API
286
500
 
287
501
  The module exposes a composition and component API to implement your `og:image` generation. You should pick
@@ -290,7 +504,7 @@ whichever one you prefer using.
290
504
  ## OgImageStatic / defineOgImageStatic
291
505
 
292
506
  The `OgImageStatic` component and the `defineOgImageStatic` composable creates a static image
293
- that will be pre-rendered.
507
+ that will be prerendered.
294
508
 
295
509
  The options follow the [OgImageOptions](#OgImageOptions) interface,
296
510
  any additional options will be passed to the `component` as props.
@@ -322,7 +536,7 @@ defineOgImageStatic({
322
536
 
323
537
  ## OgImageDynamic / defineOgImageDynamic
324
538
 
325
- The `OgImageDynamic` component and the `defineOgImageDynamic` composable creates a dynamic image. They are not pre-rendered and will
539
+ The `OgImageDynamic` component and the `defineOgImageDynamic` composable creates a dynamic image. They are not prerendered and will
326
540
  be generated at runtime.
327
541
 
328
542
  The options follow the [OgImageOptions](#OgImageOptions) interface,
@@ -396,12 +610,14 @@ The name of the component to use as the template. By default, it uses OgImageBas
396
610
  - Required: `false`
397
611
 
398
612
  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.
613
+ When you use `browser` it will use Playwright to generate the image.
400
614
 
401
- ### `prerender`
615
+ ### `static`
402
616
 
403
617
  - Type: `boolean`
404
- - Default: `true` when static, `false` when dynamic
618
+ - Default: `true` when using `defineOgImageStatic`, `false` when dynamic
619
+
620
+ Controls the prerendering of the image. A non-static image is one that will be generated at runtime and not cached.
405
621
 
406
622
 
407
623
  ## OgImageScreenshot / defineOgImageScreenshot
@@ -495,13 +711,13 @@ defineOgImageScreenshot({
495
711
 
496
712
  ## Module Config
497
713
 
498
- ### `host`
714
+ ### `siteUrl`
499
715
 
500
716
  - Type: `string`
501
717
  - Default: `undefined`
502
718
  - Required: `true`
503
719
 
504
- The host of your site. This is required to generate the absolute path of the `og:image`.
720
+ The site URL of your site. This is required when prerendering to generate the absolute path of the `og:image`.
505
721
 
506
722
  ### `defaults`
507
723
 
@@ -511,15 +727,6 @@ The host of your site. This is required to generate the absolute path of the `og
511
727
 
512
728
  The default options to use when generating images.
513
729
 
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
730
  ### `fonts`
524
731
 
525
732
  - Type: ``${string}:${number}`[]`
@@ -546,16 +753,21 @@ export default defineNuxtConfig({
546
753
 
547
754
  Options to pass to Satori when generating images. See the [Satori docs](https://github.com/vercel/satori).
548
755
 
549
- ### `experimentalNitroBrowser` (experimental)
756
+ ### `runtimeSatori`
550
757
 
551
758
  - Type: `boolean`
552
- - Default: `false`
553
- - Required: `false`
759
+ - Default: `true`
760
+
761
+ Whether to use Satori at runtime. This is useful to disable if you're prerendering all your images.
762
+
763
+ ### `runtimeBrowser`
764
+
765
+ - Type: `boolean`
766
+ - Default: `process.dev`
554
767
 
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.
768
+ Whether to use Playwright at runtime. You will need to enable this for production environments and ensure you are using
769
+ a supported nitro preset and have the required dependencies.
557
770
 
558
- This is experimental and may not work in all environments.
559
771
 
560
772
  ## Examples
561
773
 
@@ -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.74018bda.js"><link rel="preload" as="style" href="/__nuxt_og_image__/client/_nuxt/entry.7a8c1ab2.css"><link rel="prefetch" as="script" crossorigin href="/__nuxt_og_image__/client/_nuxt/error-component.cf7543e5.js"><link rel="stylesheet" href="/__nuxt_og_image__/client/_nuxt/entry.7a8c1ab2.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.9627f7dd.js"><link rel="preload" as="style" href="/__nuxt_og_image__/client/_nuxt/entry.f4586a2b.css"><link rel="prefetch" as="script" crossorigin href="/__nuxt_og_image__/client/_nuxt/error-component.4733114a.js"><link rel="stylesheet" href="/__nuxt_og_image__/client/_nuxt/entry.f4586a2b.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"}
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.74018bda.js" crossorigin></script></body>
6
+ <body ><div id="__nuxt"></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.9627f7dd.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.74018bda.js"><link rel="preload" as="style" href="/__nuxt_og_image__/client/_nuxt/entry.7a8c1ab2.css"><link rel="prefetch" as="script" crossorigin href="/__nuxt_og_image__/client/_nuxt/error-component.cf7543e5.js"><link rel="stylesheet" href="/__nuxt_og_image__/client/_nuxt/entry.7a8c1ab2.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.9627f7dd.js"><link rel="preload" as="style" href="/__nuxt_og_image__/client/_nuxt/entry.f4586a2b.css"><link rel="prefetch" as="script" crossorigin href="/__nuxt_og_image__/client/_nuxt/error-component.4733114a.js"><link rel="stylesheet" href="/__nuxt_og_image__/client/_nuxt/entry.f4586a2b.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"}
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.74018bda.js" crossorigin></script></body>
6
+ <body ><div id="__nuxt"></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.9627f7dd.js" crossorigin></script></body>
7
7
  </html>
@@ -0,0 +1 @@
1
+ import{a as r,b as u,e as p,f as t,o as l,h as _,i as d,j as m}from"./entry.9627f7dd.js";const f=r({__name:"IconCSS",props:{name:{type:String,required:!0},size:{type:String,default:""}},setup(a){const s=a;u(e=>({"243647bc":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:d({width:o.value,height:o.value})},null,4))}});const g=m(f,[["__scopeId","data-v-46d643c4"]]);export{g as default};
@@ -0,0 +1 @@
1
+ span[data-v-46d643c4]{background-color:currentColor;display:inline-block;-webkit-mask-image:var(--243647bc);mask-image:var(--243647bc);-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
+ import{a as _,r as c,m,w as r,f as u,s as d,o as g,h as f,i as y,j as v}from"./entry.9627f7dd.js";const x=_({__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,p=Date.now();t.src="",o.value=0,t.style.opacity="0",t.onload=()=>{t.style.opacity="1",o.value=Date.now()-p},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 w=v(x,[["__scopeId","data-v-23ec6856"]]);export{w as _};
@@ -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}