nuxt-og-image 3.0.0-rc.2 → 3.0.0-rc.4

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 (29) hide show
  1. package/README.md +0 -4
  2. package/dist/client/200.html +4 -4
  3. package/dist/client/404.html +4 -4
  4. package/dist/client/_nuxt/{IconCSS.12878ccd.js → IconCSS.921d8bb4.js} +1 -1
  5. package/dist/client/_nuxt/builds/latest.json +1 -1
  6. package/dist/client/_nuxt/builds/meta/f3272063-a39c-4336-ba58-ab7e348c7608.json +1 -0
  7. package/dist/client/_nuxt/{entry.e9f3db7f.js → entry.81e38674.js} +47 -47
  8. package/dist/client/_nuxt/{error-404.4c6f5cb5.js → error-404.3430ff98.js} +1 -1
  9. package/dist/client/_nuxt/{error-500.64875434.js → error-500.17781b5f.js} +1 -1
  10. package/dist/client/index.html +4 -4
  11. package/dist/module.d.mts +4 -0
  12. package/dist/module.d.ts +4 -0
  13. package/dist/module.json +1 -1
  14. package/dist/module.mjs +7 -3
  15. package/dist/runtime/cache.d.ts +2 -1
  16. package/dist/runtime/cache.mjs +33 -18
  17. package/dist/runtime/composables/defineOgImage.mjs +5 -2
  18. package/dist/runtime/core/html/fetchIsland.mjs +1 -1
  19. package/dist/runtime/core/options/fetch.mjs +7 -1
  20. package/dist/runtime/core/renderers/chromium/index.mjs +2 -1
  21. package/dist/runtime/core/utils/resolveRendererContext.mjs +10 -8
  22. package/dist/runtime/nitro/utils.mjs +1 -1
  23. package/dist/runtime/nuxt/utils.mjs +4 -1
  24. package/dist/runtime/server/routes/__og-image__/font-[name]-[weight].[extension].mjs +2 -2
  25. package/dist/runtime/server/routes/__og-image__/image.mjs +5 -3
  26. package/dist/runtime/types.d.ts +4 -0
  27. package/dist/runtime/utils.pure.mjs +1 -0
  28. package/package.json +4 -4
  29. package/dist/client/_nuxt/builds/meta/5aeabb75-f7c0-4eb8-a883-25ad30a518dd.json +0 -1
@@ -1 +1 @@
1
- import{_ as a,u as n,o as r,c as l,a as e,t as s,b as d,w as c,d as p,e as f,p as x,f as h}from"./entry.e9f3db7f.js";const m=t=>(x("data-v-05a2b8a3"),t=t(),h(),t),u={class:"font-sans antialiased bg-white dark:bg-black text-black dark:text-white grid min-h-screen place-content-center overflow-hidden"},g=m(()=>e("div",{class:"fixed left-0 right-0 spotlight z-10"},null,-1)),b={class:"max-w-520px text-center z-20"},_=["textContent"],w=["textContent"],y={class:"w-full flex items-center justify-center"},S={__name:"error-404",props:{appName:{type:String,default:"Nuxt"},version:{type:String,default:""},statusCode:{type:Number,default:404},statusMessage:{type:String,default:"Not Found"},description:{type:String,default:"Sorry, the page you are looking for could not be found."},backHome:{type:String,default:"Go back home"}},setup(t){const o=t;return n({title:`${o.statusCode} - ${o.statusMessage} | ${o.appName}`,script:[],style:[{children:'*,:before,:after{-webkit-box-sizing:border-box;box-sizing:border-box;border-width:0;border-style:solid;border-color:#e0e0e0}*{--tw-ring-inset:var(--tw-empty, );--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(14, 165, 233, .5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000}:root{-moz-tab-size:4;-o-tab-size:4;tab-size:4}a{color:inherit;text-decoration:inherit}body{margin:0;font-family:inherit;line-height:inherit}html{-webkit-text-size-adjust:100%;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";line-height:1.5}h1,p{margin:0}h1{font-size:inherit;font-weight:inherit}'}]}),(k,v)=>{const i=f;return r(),l("div",u,[g,e("div",b,[e("h1",{class:"text-8xl sm:text-10xl font-medium mb-8",textContent:s(t.statusCode)},null,8,_),e("p",{class:"text-xl px-8 sm:px-0 sm:text-4xl font-light mb-16 leading-tight",textContent:s(t.description)},null,8,w),e("div",y,[d(i,{to:"/",class:"gradient-border text-md sm:text-xl py-2 px-4 sm:py-3 sm:px-6 cursor-pointer"},{default:c(()=>[p(s(t.backHome),1)]),_:1})])])])}}},z=a(S,[["__scopeId","data-v-05a2b8a3"]]);export{z as default};
1
+ import{_ as a,u as n,o as r,c as l,a as e,t as s,b as d,w as c,d as p,e as f,p as x,f as h}from"./entry.81e38674.js";const m=t=>(x("data-v-05a2b8a3"),t=t(),h(),t),u={class:"font-sans antialiased bg-white dark:bg-black text-black dark:text-white grid min-h-screen place-content-center overflow-hidden"},g=m(()=>e("div",{class:"fixed left-0 right-0 spotlight z-10"},null,-1)),b={class:"max-w-520px text-center z-20"},_=["textContent"],w=["textContent"],y={class:"w-full flex items-center justify-center"},S={__name:"error-404",props:{appName:{type:String,default:"Nuxt"},version:{type:String,default:""},statusCode:{type:Number,default:404},statusMessage:{type:String,default:"Not Found"},description:{type:String,default:"Sorry, the page you are looking for could not be found."},backHome:{type:String,default:"Go back home"}},setup(t){const o=t;return n({title:`${o.statusCode} - ${o.statusMessage} | ${o.appName}`,script:[],style:[{children:'*,:before,:after{-webkit-box-sizing:border-box;box-sizing:border-box;border-width:0;border-style:solid;border-color:#e0e0e0}*{--tw-ring-inset:var(--tw-empty, );--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(14, 165, 233, .5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000}:root{-moz-tab-size:4;-o-tab-size:4;tab-size:4}a{color:inherit;text-decoration:inherit}body{margin:0;font-family:inherit;line-height:inherit}html{-webkit-text-size-adjust:100%;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";line-height:1.5}h1,p{margin:0}h1{font-size:inherit;font-weight:inherit}'}]}),(k,v)=>{const i=f;return r(),l("div",u,[g,e("div",b,[e("h1",{class:"text-8xl sm:text-10xl font-medium mb-8",textContent:s(t.statusCode)},null,8,_),e("p",{class:"text-xl px-8 sm:px-0 sm:text-4xl font-light mb-16 leading-tight",textContent:s(t.description)},null,8,w),e("div",y,[d(i,{to:"/",class:"gradient-border text-md sm:text-xl py-2 px-4 sm:py-3 sm:px-6 cursor-pointer"},{default:c(()=>[p(s(t.backHome),1)]),_:1})])])])}}},z=a(S,[["__scopeId","data-v-05a2b8a3"]]);export{z as default};
@@ -1 +1 @@
1
- import{_ as i,u as a,o as r,c as n,a as e,t as s,p as l,f as d}from"./entry.e9f3db7f.js";const c=t=>(l("data-v-c967d9a9"),t=t(),d(),t),p={class:"font-sans antialiased bg-white dark:bg-black text-black dark:text-white grid min-h-screen place-content-center overflow-hidden"},h=c(()=>e("div",{class:"fixed -bottom-1/2 left-0 right-0 h-1/2 spotlight"},null,-1)),f={class:"max-w-520px text-center"},g=["textContent"],m=["textContent"],x={__name:"error-500",props:{appName:{type:String,default:"Nuxt"},version:{type:String,default:""},statusCode:{type:Number,default:500},statusMessage:{type:String,default:"Server error"},description:{type:String,default:"This page is temporarily unavailable."}},setup(t){const o=t;return a({title:`${o.statusCode} - ${o.statusMessage} | ${o.appName}`,script:[],style:[{children:'*,:before,:after{-webkit-box-sizing:border-box;box-sizing:border-box;border-width:0;border-style:solid;border-color:#e0e0e0}*{--tw-ring-inset:var(--tw-empty, );--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(14, 165, 233, .5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000}:root{-moz-tab-size:4;-o-tab-size:4;tab-size:4}body{margin:0;font-family:inherit;line-height:inherit}html{-webkit-text-size-adjust:100%;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";line-height:1.5}h1,p{margin:0}h1{font-size:inherit;font-weight:inherit}'}]}),(u,b)=>(r(),n("div",p,[h,e("div",f,[e("h1",{class:"text-8xl sm:text-10xl font-medium mb-8",textContent:s(t.statusCode)},null,8,g),e("p",{class:"text-xl px-8 sm:px-0 sm:text-4xl font-light mb-16 leading-tight",textContent:s(t.description)},null,8,m)])]))}},w=i(x,[["__scopeId","data-v-c967d9a9"]]);export{w as default};
1
+ import{_ as i,u as a,o as r,c as n,a as e,t as s,p as l,f as d}from"./entry.81e38674.js";const c=t=>(l("data-v-c967d9a9"),t=t(),d(),t),p={class:"font-sans antialiased bg-white dark:bg-black text-black dark:text-white grid min-h-screen place-content-center overflow-hidden"},h=c(()=>e("div",{class:"fixed -bottom-1/2 left-0 right-0 h-1/2 spotlight"},null,-1)),f={class:"max-w-520px text-center"},g=["textContent"],m=["textContent"],x={__name:"error-500",props:{appName:{type:String,default:"Nuxt"},version:{type:String,default:""},statusCode:{type:Number,default:500},statusMessage:{type:String,default:"Server error"},description:{type:String,default:"This page is temporarily unavailable."}},setup(t){const o=t;return a({title:`${o.statusCode} - ${o.statusMessage} | ${o.appName}`,script:[],style:[{children:'*,:before,:after{-webkit-box-sizing:border-box;box-sizing:border-box;border-width:0;border-style:solid;border-color:#e0e0e0}*{--tw-ring-inset:var(--tw-empty, );--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(14, 165, 233, .5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000}:root{-moz-tab-size:4;-o-tab-size:4;tab-size:4}body{margin:0;font-family:inherit;line-height:inherit}html{-webkit-text-size-adjust:100%;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";line-height:1.5}h1,p{margin:0}h1{font-size:inherit;font-weight:inherit}'}]}),(u,b)=>(r(),n("div",p,[h,e("div",f,[e("h1",{class:"text-8xl sm:text-10xl font-medium mb-8",textContent:s(t.statusCode)},null,8,g),e("p",{class:"text-xl px-8 sm:px-0 sm:text-4xl font-light mb-16 leading-tight",textContent:s(t.description)},null,8,m)])]))}},w=i(x,[["__scopeId","data-v-c967d9a9"]]);export{w as default};
@@ -3,13 +3,13 @@
3
3
  <head><meta charset="utf-8">
4
4
  <meta name="viewport" content="width=device-width, initial-scale=1">
5
5
  <link rel="stylesheet" href="/__nuxt-og-image/_nuxt/entry.a30f63d0.css">
6
- <link rel="modulepreload" as="script" crossorigin href="/__nuxt-og-image/_nuxt/entry.e9f3db7f.js">
6
+ <link rel="modulepreload" as="script" crossorigin href="/__nuxt-og-image/_nuxt/entry.81e38674.js">
7
7
  <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/vanilla-picker-NKbIFE8h.23409a58.js">
8
8
  <link rel="prefetch" as="style" href="/__nuxt-og-image/_nuxt/error-404.b751fa02.css">
9
- <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/error-404.4c6f5cb5.js">
9
+ <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/error-404.3430ff98.js">
10
10
  <link rel="prefetch" as="style" href="/__nuxt-og-image/_nuxt/error-500.69009e70.css">
11
- <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/error-500.64875434.js">
12
- <script type="module" src="/__nuxt-og-image/_nuxt/entry.e9f3db7f.js" crossorigin></script><script>"use strict";(()=>{const a=window,e=document.documentElement,m=["dark","light"],c=window&&window.localStorage&&window.localStorage.getItem&&window.localStorage.getItem("nuxt-color-mode")||"system";let n=c==="system"?d():c;const l=e.getAttribute("data-color-mode-forced");l&&(n=l),i(n),a["__NUXT_COLOR_MODE__"]={preference:c,value:n,getColorScheme:d,addColorScheme:i,removeColorScheme:f};function i(o){const t=""+o+"",s="";e.classList?e.classList.add(t):e.className+=" "+t,s&&e.setAttribute("data-"+s,o)}function f(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 d(){if(a.matchMedia&&r("").media!=="not all"){for(const o of m)if(r(":"+o).matches)return o}return"light"}})();
11
+ <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/error-500.17781b5f.js">
12
+ <script type="module" src="/__nuxt-og-image/_nuxt/entry.81e38674.js" crossorigin></script><script>"use strict";(()=>{const a=window,e=document.documentElement,m=["dark","light"],c=window&&window.localStorage&&window.localStorage.getItem&&window.localStorage.getItem("nuxt-color-mode")||"system";let n=c==="system"?d():c;const l=e.getAttribute("data-color-mode-forced");l&&(n=l),i(n),a["__NUXT_COLOR_MODE__"]={preference:c,value:n,getColorScheme:d,addColorScheme:i,removeColorScheme:f};function i(o){const t=""+o+"",s="";e.classList?e.classList.add(t):e.className+=" "+t,s&&e.setAttribute("data-"+s,o)}function f(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 d(){if(a.matchMedia&&r("").media!=="not all"){for(const o of m)if(r(":"+o).matches)return o}return"light"}})();
13
13
  </script></head>
14
14
  <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>
15
15
  <script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__nuxt-og-image",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script></body>
package/dist/module.d.mts CHANGED
@@ -80,6 +80,10 @@ interface OgImageOptions<T extends keyof OgImageComponents = 'NuxtSeo'> {
80
80
  sharp?: SharpOptions;
81
81
  fonts?: InputFontConfig[];
82
82
  cacheMaxAgeSeconds?: number;
83
+ /**
84
+ * @internal
85
+ */
86
+ _query?: Record<string, any>;
83
87
  }
84
88
  interface FontConfig {
85
89
  name: string;
package/dist/module.d.ts CHANGED
@@ -80,6 +80,10 @@ interface OgImageOptions<T extends keyof OgImageComponents = 'NuxtSeo'> {
80
80
  sharp?: SharpOptions;
81
81
  fonts?: InputFontConfig[];
82
82
  cacheMaxAgeSeconds?: number;
83
+ /**
84
+ * @internal
85
+ */
86
+ _query?: Record<string, any>;
83
87
  }
84
88
  interface FontConfig {
85
89
  name: string;
package/dist/module.json CHANGED
@@ -5,5 +5,5 @@
5
5
  "bridge": false
6
6
  },
7
7
  "configKey": "ogImage",
8
- "version": "3.0.0-rc.2"
8
+ "version": "3.0.0-rc.4"
9
9
  }
package/dist/module.mjs CHANGED
@@ -14,7 +14,7 @@ import { createHash } from 'node:crypto';
14
14
  import { execa } from 'execa';
15
15
  import terminate from 'terminate';
16
16
 
17
- const version = "3.0.0-rc.2";
17
+ const version = "3.0.0-rc.4";
18
18
 
19
19
  const autodetectableProviders = {
20
20
  azure_static: "azure",
@@ -628,7 +628,7 @@ declare module 'nitropack' {
628
628
  }
629
629
  interface NitroRuntimeHooks {
630
630
  'nuxt-og-image:context': (ctx: import('${typesPath}').OgImageRenderEventContext) => void | Promise<void>
631
- 'nuxt-og-image:satori:vnodes': (vnodes: import('${typesPath}').VNode, ctx: ctx: import('${typesPath}').OgImageRenderEventContext) => void | Promise<void>
631
+ 'nuxt-og-image:satori:vnodes': (vnodes: import('${typesPath}').VNode, ctx: import('${typesPath}').OgImageRenderEventContext) => void | Promise<void>
632
632
  }
633
633
  }
634
634
 
@@ -641,9 +641,13 @@ ${componentImports}
641
641
  });
642
642
  const cacheEnabled = typeof config.runtimeCacheStorage !== "undefined" && config.runtimeCacheStorage !== false;
643
643
  const runtimeCacheStorage = typeof config.runtimeCacheStorage === "boolean" ? "default" : config.runtimeCacheStorage.driver;
644
- let baseCacheKey = runtimeCacheStorage === "default" ? `/cache/nuxt-og-image@${version}` : `/nuxt-og-image@${version}`;
644
+ let baseCacheKey = runtimeCacheStorage === "default" ? `/cache/nuxt-og-image@${version}` : `/nuxt-og-image/${version}`;
645
645
  if (!cacheEnabled)
646
646
  baseCacheKey = false;
647
+ if (!nuxt.options.dev && config.runtimeCacheStorage && typeof config.runtimeCacheStorage === "object") {
648
+ nuxt.options.nitro.storage = nuxt.options.nitro.storage || {};
649
+ nuxt.options.nitro.storage["nuxt-og-image"] = config.runtimeCacheStorage;
650
+ }
647
651
  nuxt.hooks.hook("modules:done", async () => {
648
652
  const normalisedFonts = normaliseFontInput(config.fonts);
649
653
  if (!nuxt.options._generate && nuxt.options.build) {
@@ -1,8 +1,9 @@
1
+ import { type H3Error } from 'h3';
1
2
  import type { OgImageRenderEventContext } from './types';
2
3
  export declare function useOgImageBufferCache(ctx: OgImageRenderEventContext, options: {
3
4
  baseCacheKey: string | false;
4
5
  cacheMaxAgeSeconds?: number;
5
- }): Promise<void | {
6
+ }): Promise<void | H3Error | {
6
7
  cachedItem: false | BufferSource;
7
8
  enabled: boolean;
8
9
  update: (image: BufferSource) => Promise<void>;
@@ -1,31 +1,46 @@
1
1
  import { prefixStorage } from "unstorage";
2
- import { getQuery, handleCacheHeaders, setHeader, setHeaders } from "h3";
2
+ import { createError, getQuery, handleCacheHeaders, setHeader, setHeaders } from "h3";
3
3
  import { withTrailingSlash } from "ufo";
4
4
  import { hash } from "ohash";
5
5
  import { useStorage } from "#imports";
6
6
  export async function useOgImageBufferCache(ctx, options) {
7
7
  const maxAge = Number(options.cacheMaxAgeSeconds);
8
- const enabled = !import.meta.dev && import.meta.env.MODE !== "test" && maxAge > 0;
8
+ let enabled = !import.meta.dev && import.meta.env.MODE !== "test" && maxAge > 0;
9
9
  const cache = prefixStorage(useStorage(), withTrailingSlash(options.baseCacheKey || "/"));
10
10
  const key = ctx.key;
11
11
  let cachedItem = false;
12
- if (enabled && await cache.hasItem(key).catch(() => false)) {
13
- const { value, expiresAt, headers } = await cache.getItem(key).catch(() => ({ value: null, expiresAt: Date.now() }));
14
- if (typeof getQuery(ctx.e).purge !== "undefined") {
15
- await cache.removeItem(key).catch(() => {
16
- });
17
- } else if (expiresAt > Date.now()) {
18
- cachedItem = Buffer.from(value, "base64");
19
- if (handleCacheHeaders(ctx.e, {
20
- modifiedTime: new Date(headers["last-modified"]),
21
- etag: headers.etag,
22
- maxAge
23
- }))
24
- return;
25
- setHeaders(ctx.e, headers);
26
- } else {
27
- await cache.removeItem(key).catch(() => {
12
+ if (enabled) {
13
+ const hasItem = await cache.hasItem(key).catch((e) => {
14
+ enabled = false;
15
+ return createError({
16
+ cause: e,
17
+ statusCode: 500,
18
+ statusMessage: `[Nuxt OG Image] Failed to connect to cache ${options.baseCacheKey}. Response from cache: ${e.message}`
28
19
  });
20
+ });
21
+ if (hasItem instanceof Error)
22
+ return hasItem;
23
+ if (hasItem) {
24
+ const { value, expiresAt, headers } = await cache.getItem(key).catch(() => ({
25
+ value: null,
26
+ expiresAt: Date.now()
27
+ }));
28
+ if (typeof getQuery(ctx.e).purge !== "undefined") {
29
+ await cache.removeItem(key).catch(() => {
30
+ });
31
+ } else if (expiresAt > Date.now()) {
32
+ cachedItem = Buffer.from(value, "base64");
33
+ if (handleCacheHeaders(ctx.e, {
34
+ modifiedTime: new Date(headers["last-modified"]),
35
+ etag: headers.etag,
36
+ maxAge
37
+ }))
38
+ return;
39
+ setHeaders(ctx.e, headers);
40
+ } else {
41
+ await cache.removeItem(key).catch(() => {
42
+ });
43
+ }
29
44
  }
30
45
  }
31
46
  if (!enabled) {
@@ -4,13 +4,14 @@ import { createRouter as createRadixRouter, toRouteMatcher } from "radix3";
4
4
  import { withoutBase } from "ufo";
5
5
  import { getOgImagePath, separateProps, useOgImageRuntimeConfig } from "../utils.mjs";
6
6
  import { createOgImageMeta, normaliseOptions } from "../nuxt/utils.mjs";
7
- import { useNuxtApp, useRequestEvent, useRouter, useRuntimeConfig } from "#imports";
7
+ import { useNuxtApp, useRequestEvent, useRoute, useRuntimeConfig } from "#imports";
8
8
  export function defineOgImage(_options = {}) {
9
9
  if (!import.meta.server)
10
10
  return;
11
11
  const nuxtApp = useNuxtApp();
12
12
  const ogImageInstances = nuxtApp.ssrContext._ogImageInstances || [];
13
- const basePath = useRouter().currentRoute.value?.path || "/";
13
+ const route = useRoute();
14
+ const basePath = route.path || "/";
14
15
  const _routeRulesMatcher = toRouteMatcher(
15
16
  createRadixRouter({ routes: useRuntimeConfig().nitro?.routeRules })
16
17
  );
@@ -27,6 +28,8 @@ export function defineOgImage(_options = {}) {
27
28
  const options = normaliseOptions({
28
29
  ..._options
29
30
  });
31
+ if (route.query)
32
+ options._query = route.query;
30
33
  const { defaults } = useOgImageRuntimeConfig();
31
34
  const resolvedOptions = normaliseOptions(defu(separateProps(_options), separateProps(routeRules), defaults));
32
35
  if (_options.url) {
@@ -4,7 +4,7 @@ export function fetchIsland({ options, e }) {
4
4
  if (!options.component) {
5
5
  throw createError({
6
6
  statusCode: 500,
7
- statusMessage: `Nuxt OG Image trying to render an invalid component. Received options ${JSON.stringify(options)}`
7
+ statusMessage: `[Nuxt OG Image] Rendering an invalid component. Received options: ${JSON.stringify(options)}.`
8
8
  });
9
9
  }
10
10
  const hashId = hash([options.component, options]);
@@ -11,7 +11,13 @@ export async function fetchPathHtmlAndExtractOptions(e, path, key) {
11
11
  } catch (err) {
12
12
  return createError({
13
13
  statusCode: 500,
14
- statusMessage: `Failed to read the path ${path} for og-image extraction. ${err.message}.`
14
+ statusMessage: `[Nuxt OG Image] Failed to read the path ${path} for og-image extraction. ${err.message}.`
15
+ });
16
+ }
17
+ if (typeof html !== "string") {
18
+ return createError({
19
+ statusCode: 500,
20
+ statusMessage: `[Nuxt OG Image] Got invalid response from ${path} for og-image extraction.`
15
21
  });
16
22
  }
17
23
  const payload = extractAndNormaliseOgImageOptions(html);
@@ -14,7 +14,8 @@ const ChromiumRenderer = {
14
14
  if (screenshot instanceof Error) {
15
15
  return createError({
16
16
  statusCode: 400,
17
- statusMessage: `Failed to create screenshot ${screenshot.message}.`
17
+ cause: screenshot,
18
+ statusMessage: `[Nuxt OG Image] Failed to create screenshot ${screenshot.message}.`
18
19
  });
19
20
  }
20
21
  return screenshot;
@@ -1,4 +1,4 @@
1
- import { parseURL, withoutBase, withoutTrailingSlash } from "ufo";
1
+ import { parseURL, withQuery, withoutBase, withoutTrailingSlash } from "ufo";
2
2
  import { createError, getQuery } from "h3";
3
3
  import { defu } from "defu";
4
4
  import { createRouter as createRadixRouter, toRouteMatcher } from "radix3";
@@ -15,21 +15,23 @@ export async function resolveRendererContext(e) {
15
15
  if (!extension) {
16
16
  return createError({
17
17
  statusCode: 400,
18
- statusMessage: `Missing OG Image type.`
18
+ statusMessage: `[Nuxt OG Image] Missing OG Image type.`
19
19
  });
20
20
  }
21
21
  if (!["png", "jpeg", "jpg", "svg", "html", "json"].includes(extension)) {
22
22
  return createError({
23
23
  statusCode: 400,
24
- statusMessage: `Unknown OG Image type ${extension}.`
24
+ statusMessage: `[Nuxt OG Image] Unknown OG Image type ${extension}.`
25
25
  });
26
26
  }
27
- const basePath = withoutTrailingSlash(
28
- path.replace(`/__og-image__/image`, "").replace(`/og.${extension}`, "")
29
- );
30
27
  let queryParams = { ...getQuery(e) };
31
28
  queryParams.props = JSON.parse(queryParams.props || "{}");
32
29
  queryParams = separateProps(queryParams);
30
+ let basePath = withoutTrailingSlash(
31
+ path.replace(`/__og-image__/image`, "").replace(`/og.${extension}`, "")
32
+ );
33
+ if (queryParams._query)
34
+ basePath = withQuery(basePath, JSON.parse(queryParams._query));
33
35
  const isDebugJsonPayload = extension === "json" && runtimeConfig.debug;
34
36
  const key = resolvePathCacheKey(e, basePath);
35
37
  let options = queryParams.options;
@@ -61,7 +63,7 @@ export async function resolveRendererContext(e) {
61
63
  if (!options) {
62
64
  return createError({
63
65
  statusCode: 404,
64
- statusMessage: "OG Image not found."
66
+ statusMessage: "[Nuxt OG Image] OG Image not found."
65
67
  });
66
68
  }
67
69
  let renderer;
@@ -76,7 +78,7 @@ export async function resolveRendererContext(e) {
76
78
  if (!renderer || renderer.__unenv__) {
77
79
  throw createError({
78
80
  statusCode: 400,
79
- statusMessage: `Renderer ${options.renderer} is missing.`
81
+ statusMessage: `[Nuxt OG Image] Renderer ${options.renderer} is missing.`
80
82
  });
81
83
  }
82
84
  const ctx = {
@@ -7,7 +7,7 @@ export function resolvePathCacheKey(e, path) {
7
7
  const siteConfig = useSiteConfig(e);
8
8
  const basePath = withoutTrailingSlash(withoutLeadingSlash(normalizeKey(path || e.path)));
9
9
  return [
10
- !basePath ? "index" : basePath,
10
+ !basePath || basePath === "/" ? "index" : basePath,
11
11
  hash([
12
12
  basePath,
13
13
  siteConfig.url,
@@ -1,10 +1,13 @@
1
1
  import { defu } from "defu";
2
+ import { withQuery } from "ufo";
2
3
  import { separateProps } from "../utils.mjs";
3
4
  import { unref, useServerHead } from "#imports";
4
5
  import { componentNames } from "#build/nuxt-og-image/components.mjs";
5
6
  export function createOgImageMeta(src, input, resolvedOptions, ssrContext) {
6
7
  const _input = separateProps(defu(input, ssrContext._ogImagePayload));
7
- const url = src || input.url || resolvedOptions.url;
8
+ let url = src || input.url || resolvedOptions.url;
9
+ if (input._query && url)
10
+ url = withQuery(url, { _query: input._query });
8
11
  let urlExtension = (url.split("/").pop() || url).split(".").pop() || resolvedOptions.extension;
9
12
  if (urlExtension === "jpg")
10
13
  urlExtension = "jpeg";
@@ -14,7 +14,7 @@ export default defineEventHandler(async (e) => {
14
14
  if (!css) {
15
15
  return createError({
16
16
  statusCode: 500,
17
- statusMessage: `Invalid Google Font ${name}:${weight}`
17
+ statusMessage: `[Nuxt OG Image] Invalid Google Font ${name}:${weight}`
18
18
  });
19
19
  }
20
20
  const ttfResource = css.match(/src: url\((.+)\) format\('(opentype|truetype)'\)/);
@@ -25,6 +25,6 @@ export default defineEventHandler(async (e) => {
25
25
  return sendRedirect(e, woff2Resource[1]);
26
26
  return createError({
27
27
  statusCode: 500,
28
- statusMessage: `Malformed Google Font CSS ${css}`
28
+ statusMessage: `[Nuxt OG Image] Malformed Google Font CSS ${css}`
29
29
  });
30
30
  });
@@ -43,7 +43,7 @@ export default defineEventHandler(async (e) => {
43
43
  if (ctx.renderer.name !== "satori") {
44
44
  return createError({
45
45
  statusCode: 400,
46
- statusMessage: `Generating ${extension}'s with ${renderer.name} is not supported.`
46
+ statusMessage: `[Nuxt OG Image] Generating ${extension}'s with ${renderer.name} is not supported.`
47
47
  });
48
48
  }
49
49
  setHeader(e, "Content-Type", `image/svg+xml`);
@@ -54,7 +54,7 @@ export default defineEventHandler(async (e) => {
54
54
  if (!renderer.supportedFormats.includes(extension)) {
55
55
  return createError({
56
56
  statusCode: 400,
57
- statusMessage: `Generating ${extension}'s with ${renderer.name} is not supported.`
57
+ statusMessage: `[Nuxt OG Image] Generating ${extension}'s with ${renderer.name} is not supported.`
58
58
  });
59
59
  }
60
60
  setHeader(e, "Content-Type", `image/${extension === "jpg" ? "jpeg" : extension}`);
@@ -62,7 +62,7 @@ export default defineEventHandler(async (e) => {
62
62
  default:
63
63
  return createError({
64
64
  statusCode: 400,
65
- statusMessage: `Invalid request for og.${extension}.`
65
+ statusMessage: `[Nuxt OG Image] Invalid request for og.${extension}.`
66
66
  });
67
67
  }
68
68
  const cacheApi = await useOgImageBufferCache(ctx, {
@@ -71,6 +71,8 @@ export default defineEventHandler(async (e) => {
71
71
  });
72
72
  if (typeof cacheApi === "undefined")
73
73
  return;
74
+ if (cacheApi instanceof H3Error)
75
+ return cacheApi;
74
76
  let image = cacheApi.cachedItem;
75
77
  if (!image) {
76
78
  image = await renderer.createImage(ctx);
@@ -106,6 +106,10 @@ export interface OgImageOptions<T extends keyof OgImageComponents = 'NuxtSeo'> {
106
106
  sharp?: SharpOptions;
107
107
  fonts?: InputFontConfig[];
108
108
  cacheMaxAgeSeconds?: number;
109
+ /**
110
+ * @internal
111
+ */
112
+ _query?: Record<string, any>;
109
113
  }
110
114
  export interface FontConfig {
111
115
  name: string;
@@ -17,6 +17,7 @@ function filterIsOgImageOption(key) {
17
17
  "component",
18
18
  "renderer",
19
19
  "emojis",
20
+ "_query",
20
21
  "satori",
21
22
  "resvg",
22
23
  "sharp",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "nuxt-og-image",
3
3
  "type": "module",
4
- "version": "3.0.0-rc.2",
4
+ "version": "3.0.0-rc.4",
5
5
  "packageManager": "pnpm@8.12.0",
6
6
  "description": "Enlightened OG Image generation for Nuxt.",
7
7
  "author": {
@@ -42,7 +42,7 @@
42
42
  "@unocss/preset-wind": "^0.58.0",
43
43
  "@vueuse/core": "^10.7.0",
44
44
  "chrome-launcher": "^1.1.0",
45
- "css-inline": "^0.11.0",
45
+ "css-inline": "^0.11.2",
46
46
  "defu": "^6.1.3",
47
47
  "execa": "^8.0.1",
48
48
  "floating-vue": "2.0.0-beta.24",
@@ -74,7 +74,7 @@
74
74
  "@nuxtjs/i18n": "8.0.0-rc.8",
75
75
  "@nuxtjs/tailwindcss": "^6.10.1",
76
76
  "@unocss/nuxt": "^0.58.0",
77
- "bumpp": "^9.2.0",
77
+ "bumpp": "^9.2.1",
78
78
  "eslint": "8.55.0",
79
79
  "jest-image-snapshot": "^6.3.0",
80
80
  "nuxt": "^3.8.2",
@@ -82,7 +82,7 @@
82
82
  "playwright": "^1.40.1",
83
83
  "sass": "^1.69.5",
84
84
  "sharp": "^0.33.0",
85
- "vitest": "^1.0.2"
85
+ "vitest": "^1.0.4"
86
86
  },
87
87
  "build": {
88
88
  "externals": [
@@ -1 +0,0 @@
1
- {"id":"5aeabb75-f7c0-4eb8-a883-25ad30a518dd","timestamp":1702111998335,"matcher":{"static":{},"wildcard":{},"dynamic":{}},"prerendered":[]}