nuxt-og-image 3.0.0-rc.63 → 3.0.0-rc.65

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 (40) hide show
  1. package/README.md +67 -67
  2. package/dist/client/200.html +8 -8
  3. package/dist/client/404.html +8 -8
  4. package/dist/client/_nuxt/{eEwap3HF.js → DVxyIIKo.js} +1 -1
  5. package/dist/client/_nuxt/{x0e1-5KE.js → WfFM8TlZ.js} +1 -1
  6. package/dist/client/_nuxt/builds/latest.json +1 -1
  7. package/dist/client/_nuxt/builds/meta/5876a781-42f1-459e-a560-bbe16edad6b7.json +1 -0
  8. package/dist/client/_nuxt/{entry.BCfFhbeW.css → entry.BJu2ITzA.css} +1 -1
  9. package/dist/client/_nuxt/error-404.B3wjZPBT.css +1 -0
  10. package/dist/client/_nuxt/error-500.Dxoa4Ooo.css +1 -0
  11. package/dist/client/_nuxt/{DtDGQseG.js → xettH10j.js} +3 -3
  12. package/dist/client/index.html +8 -8
  13. package/dist/module.json +1 -1
  14. package/dist/module.mjs +22 -11
  15. package/dist/runtime/nitro/og-image/bindings/css-inline/node.d.ts +2 -1
  16. package/dist/runtime/nitro/og-image/bindings/css-inline/wasm-fs.d.ts +2 -3
  17. package/dist/runtime/nitro/og-image/bindings/css-inline/wasm.d.ts +2 -3
  18. package/dist/runtime/nitro/og-image/context.js +1 -1
  19. package/dist/runtime/nitro/og-image/satori/instances.d.ts +1 -2
  20. package/dist/runtime/nitro/og-image/satori/plugins/imageSrc.js +4 -0
  21. package/dist/runtime/nitro/og-image/satori/transforms/inlineCss.js +8 -0
  22. package/dist/runtime/nitro/tsconfig.json +3 -3
  23. package/dist/runtime/nitro/util/logger.d.ts +1 -0
  24. package/dist/runtime/nitro/util/logger.js +6 -0
  25. package/dist/runtime/nuxt/components/Templates/Community/BrandedLogo.vue +29 -29
  26. package/dist/runtime/nuxt/components/Templates/Community/Frame.vue +64 -64
  27. package/dist/runtime/nuxt/components/Templates/Community/Nuxt.vue +185 -185
  28. package/dist/runtime/nuxt/components/Templates/Community/NuxtSeo.vue +137 -137
  29. package/dist/runtime/nuxt/components/Templates/Community/Pergel.vue +103 -103
  30. package/dist/runtime/nuxt/components/Templates/Community/SimpleBlog.vue +35 -35
  31. package/dist/runtime/nuxt/components/Templates/Community/UnJs.vue +108 -108
  32. package/dist/runtime/nuxt/components/Templates/Community/Wave.vue +34 -34
  33. package/dist/runtime/nuxt/components/Templates/Community/WithEmoji.vue +28 -28
  34. package/dist/runtime/nuxt/plugins/og-image-canonical-urls.server.js +1 -1
  35. package/dist/runtime/nuxt/utils.js +6 -4
  36. package/package.json +2 -2
  37. package/virtual.d.ts +49 -49
  38. package/dist/client/_nuxt/builds/meta/59641a36-dc02-4d42-99e6-b1a25f3b3613.json +0 -1
  39. package/dist/client/_nuxt/error-404.BMGu0azq.css +0 -1
  40. package/dist/client/_nuxt/error-500.DUmFq9tp.css +0 -1
@@ -1,7 +1,7 @@
1
1
  <!DOCTYPE html><html data-capo=""><head><meta charset="utf-8">
2
2
  <meta name="viewport" content="width=device-width, initial-scale=1">
3
- <link rel="stylesheet" href="/__nuxt-og-image/_nuxt/entry.BCfFhbeW.css">
4
- <link rel="modulepreload" as="script" crossorigin href="/__nuxt-og-image/_nuxt/DtDGQseG.js">
3
+ <link rel="stylesheet" href="/__nuxt-og-image/_nuxt/entry.BJu2ITzA.css">
4
+ <link rel="modulepreload" as="script" crossorigin href="/__nuxt-og-image/_nuxt/xettH10j.js">
5
5
  <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/DXFkqnOI.js">
6
6
  <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/BigF1UXR.js">
7
7
  <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/CowR2XfX.js">
@@ -258,9 +258,9 @@
258
258
  <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/Bxkoe-BC.js">
259
259
  <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/Br6ll-O0.js">
260
260
  <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/B6E6ObS_.js">
261
- <link rel="prefetch" as="style" href="/__nuxt-og-image/_nuxt/error-404.BMGu0azq.css">
262
- <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/eEwap3HF.js">
263
- <link rel="prefetch" as="style" href="/__nuxt-og-image/_nuxt/error-500.DUmFq9tp.css">
264
- <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/x0e1-5KE.js">
265
- <script type="module" src="/__nuxt-og-image/_nuxt/DtDGQseG.js" crossorigin></script></head><body><div id="__nuxt"></div><div id="teleports"></div><script type="application/json" id="__NUXT_DATA__" data-ssr="false">[{"serverRendered":1},false]</script>
266
- <script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__nuxt-og-image",buildId:"59641a36-dc02-4d42-99e6-b1a25f3b3613",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script></body></html>
261
+ <link rel="prefetch" as="style" href="/__nuxt-og-image/_nuxt/error-404.B3wjZPBT.css">
262
+ <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/DVxyIIKo.js">
263
+ <link rel="prefetch" as="style" href="/__nuxt-og-image/_nuxt/error-500.Dxoa4Ooo.css">
264
+ <link rel="prefetch" as="script" crossorigin href="/__nuxt-og-image/_nuxt/WfFM8TlZ.js">
265
+ <script type="module" src="/__nuxt-og-image/_nuxt/xettH10j.js" crossorigin></script></head><body><div id="__nuxt"></div><div id="teleports"></div><script type="application/json" id="__NUXT_DATA__" data-ssr="false">[{"serverRendered":1},false]</script>
266
+ <script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__nuxt-og-image",buildId:"5876a781-42f1-459e-a560-bbe16edad6b7",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script></body></html>
package/dist/module.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "bridge": false
6
6
  },
7
7
  "configKey": "ogImage",
8
- "version": "3.0.0-rc.62",
8
+ "version": "3.0.0-rc.64",
9
9
  "builder": {
10
10
  "@nuxt/module-builder": "0.8.1",
11
11
  "unbuild": "2.0.0"
package/dist/module.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as fs from 'node:fs';
2
2
  import { existsSync } from 'node:fs';
3
3
  import { readFile, writeFile } from 'node:fs/promises';
4
- import { useNuxt, addTemplate, loadNuxtModuleInstance, createResolver, resolvePath, tryResolveModule, defineNuxtModule, useLogger, addImports, hasNuxtModule, addServerPlugin, addServerHandler, addComponentsDir, addComponent, addPlugin } from '@nuxt/kit';
4
+ import { useNuxt, tryResolveModule, addTemplate, loadNuxtModuleInstance, createResolver, resolvePath, defineNuxtModule, useLogger, addImports, hasNuxtModule, addServerPlugin, addServerHandler, addComponentsDir, addComponent, addPlugin } from '@nuxt/kit';
5
5
  import { assertSiteConfig, installNuxtSiteConfig } from 'nuxt-site-config-kit';
6
6
  import { provider, env, isCI, isDevelopment } from 'std-env';
7
7
  import { hash } from 'ohash';
@@ -35,7 +35,7 @@ const NodeRuntime = {
35
35
  // node-server runtime
36
36
  "chromium": "on-demand",
37
37
  // this gets changed build start
38
- "css-inline": "wasm",
38
+ "css-inline": "node",
39
39
  "resvg": "node",
40
40
  "satori": "node",
41
41
  "sharp": "node"
@@ -122,7 +122,7 @@ function resolveNitroPreset(nitroConfig) {
122
122
  if (nitroConfig && nitroConfig?.preset)
123
123
  preset = nitroConfig.preset;
124
124
  if (!preset)
125
- preset = env.NITRO_PRESET || detectTarget() || "node-server";
125
+ preset = env.NITRO_PRESET || env.SERVER_PRESET || detectTarget() || "node-server";
126
126
  return preset.replace("_", "-");
127
127
  }
128
128
  function getPresetNitroPresetCompatibility(target) {
@@ -131,9 +131,11 @@ function getPresetNitroPresetCompatibility(target) {
131
131
  compatibility = RuntimeCompatibility["nitro-dev"];
132
132
  return compatibility;
133
133
  }
134
- function applyNitroPresetCompatibility(nitroConfig, options) {
134
+ async function applyNitroPresetCompatibility(nitroConfig, options) {
135
135
  const target = resolveNitroPreset(nitroConfig);
136
136
  const compatibility = getPresetNitroPresetCompatibility(target);
137
+ const hasCssInlineNode = !!await tryResolveModule("@css-inline/css-inline");
138
+ const hasCssInlineWasm = !!await tryResolveModule("@css-inline/css-inline-wasm");
137
139
  const { resolve } = options;
138
140
  const satoriEnabled = typeof options.compatibility?.satori !== "undefined" ? !!options.compatibility.satori : !!compatibility.satori;
139
141
  const chromiumEnabled = typeof options.compatibility?.chromium !== "undefined" ? !!options.compatibility.chromium : !!compatibility.chromium;
@@ -146,6 +148,11 @@ function applyNitroPresetCompatibility(nitroConfig, options) {
146
148
  binding = compatibility[key];
147
149
  if (key === "chromium" && binding === "node")
148
150
  binding = "playwright";
151
+ if (key === "css-inline") {
152
+ if (binding === "node" && !hasCssInlineNode || binding === "wasm" && !hasCssInlineWasm) {
153
+ binding = false;
154
+ }
155
+ }
149
156
  resolvedCompatibility[key] = binding;
150
157
  return {
151
158
  [`#nuxt-og-image/bindings/${key}`]: binding === false ? "unenv/runtime/mock/empty" : resolve(`./runtime/nitro/og-image/bindings/${key}/${binding}`)
@@ -294,13 +301,13 @@ function setupDevToolsUI(options, resolve, nuxt = useNuxt()) {
294
301
 
295
302
  function setupDevHandler(options, resolve, nuxt = useNuxt()) {
296
303
  nuxt.hooks.hook("nitro:config", async (nitroConfig) => {
297
- applyNitroPresetCompatibility(nitroConfig, { compatibility: options.compatibility?.dev, resolve });
304
+ await applyNitroPresetCompatibility(nitroConfig, { compatibility: options.compatibility?.dev, resolve });
298
305
  });
299
306
  }
300
307
 
301
308
  function setupGenerateHandler(options, resolve, nuxt = useNuxt()) {
302
309
  nuxt.hooks.hook("nitro:config", async (nitroConfig) => {
303
- applyNitroPresetCompatibility(nitroConfig, {
310
+ await applyNitroPresetCompatibility(nitroConfig, {
304
311
  compatibility: {
305
312
  "chromium": false,
306
313
  "satori": false,
@@ -321,7 +328,7 @@ function setupGenerateHandler(options, resolve, nuxt = useNuxt()) {
321
328
  function setupPrerenderHandler(options, resolve, nuxt = useNuxt()) {
322
329
  nuxt.hooks.hook("nitro:init", async (nitro) => {
323
330
  nitro.hooks.hook("prerender:config", async (nitroConfig) => {
324
- applyNitroPresetCompatibility(nitroConfig, { compatibility: options.compatibility?.prerender, resolve });
331
+ await applyNitroPresetCompatibility(nitroConfig, { compatibility: options.compatibility?.prerender, resolve });
325
332
  nitroConfig.wasm = nitroConfig.wasm || {};
326
333
  nitroConfig.wasm.esmImport = false;
327
334
  const prerenderingPages = (nuxt.options.nitro.prerender?.routes || []).some((r) => r && (!r.includes(".") || r.includes("*")));
@@ -341,7 +348,7 @@ async function setupBuildHandler(config, resolve, nuxt = useNuxt()) {
341
348
  if (typeof config.runtimeCacheStorage === "object")
342
349
  nuxt.options.nitro.storage["og-image"] = config.runtimeCacheStorage;
343
350
  nuxt.hooks.hook("nitro:config", async (nitroConfig) => {
344
- applyNitroPresetCompatibility(nitroConfig, { compatibility: config.compatibility?.runtime, resolve });
351
+ await applyNitroPresetCompatibility(nitroConfig, { compatibility: config.compatibility?.runtime, resolve });
345
352
  nitroConfig.alias.electron = "unenv/runtime/mock/proxy-cjs";
346
353
  nitroConfig.alias.bufferutil = "unenv/runtime/mock/proxy-cjs";
347
354
  nitroConfig.alias["utf-8-validate"] = "unenv/runtime/mock/proxy-cjs";
@@ -363,15 +370,19 @@ async function setupBuildHandler(config, resolve, nuxt = useNuxt()) {
363
370
  ].filter(existsSync)[0] || serverEntry;
364
371
  }
365
372
  const contents = await readFile(serverEntry, "utf-8");
366
- const resvgHash = sha1(await readFile(await resolvePath("@resvg/resvg-wasm/index_bg.wasm")));
367
- const yogaHash = sha1(await readFile(await resolvePath("yoga-wasm-web/dist/yoga.wasm")));
368
- const cssInlineHash = sha1(await readFile(await resolvePath("@css-inline/css-inline-wasm/index_bg.wasm")));
373
+ const resvgHash = await resolveFilePathSha1("@resvg/resvg-wasm/index_bg.wasm");
374
+ const yogaHash = await resolveFilePathSha1("yoga-wasm-web/dist/yoga.wasm");
375
+ const cssInlineHash = await resolveFilePathSha1("@css-inline/css-inline-wasm/index_bg.wasm");
369
376
  const postfix = target === "vercel-edge" ? "?module" : "";
370
377
  const path = isCloudflarePagesOrModule ? `../wasm/` : `./wasm/`;
371
378
  await writeFile(serverEntry, contents.replaceAll('"@resvg/resvg-wasm/index_bg.wasm?module"', `"${path}index_bg-${resvgHash}.wasm${postfix}"`).replaceAll('"@css-inline/css-inline-wasm/index_bg.wasm?module"', `"${path}index_bg-${cssInlineHash}.wasm${postfix}"`).replaceAll('"yoga-wasm-web/dist/yoga.wasm?module"', `"${path}yoga-${yogaHash}.wasm${postfix}"`), { encoding: "utf-8" });
372
379
  });
373
380
  });
374
381
  }
382
+ async function resolveFilePathSha1(path) {
383
+ const _path = await resolvePath(path);
384
+ return sha1(existsSync(_path) ? await readFile(_path) : path);
385
+ }
375
386
  function sha1(source) {
376
387
  return createHash("sha1").update(source).digest("hex").slice(0, 16);
377
388
  }
@@ -1,7 +1,8 @@
1
+ import { inline } from '@css-inline/css-inline';
1
2
  declare const _default: {
2
3
  initWasmPromise: Promise<void>;
3
4
  cssInline: {
4
- inline: any;
5
+ inline: typeof inline;
5
6
  };
6
7
  };
7
8
  export default _default;
@@ -1,8 +1,7 @@
1
- import { inline } from '@css-inline/css-inline-wasm';
2
1
  declare const _default: {
3
- initWasmPromise: Promise<void>;
2
+ initWasmPromise: any;
4
3
  cssInline: {
5
- inline: typeof inline;
4
+ inline: any;
6
5
  };
7
6
  };
8
7
  export default _default;
@@ -1,8 +1,7 @@
1
- import { inline } from '@css-inline/css-inline-wasm';
2
1
  declare const _default: {
3
- initWasmPromise: Promise<void>;
2
+ initWasmPromise: any;
4
3
  cssInline: {
5
- inline: typeof inline;
4
+ inline: any;
6
5
  };
7
6
  };
8
7
  export default _default;
@@ -3,7 +3,7 @@ import { createError, getQuery } from "h3";
3
3
  import { defu } from "defu";
4
4
  import { normalizeKey } from "unstorage";
5
5
  import { hash } from "ohash";
6
- import { useNitroApp } from "nitropack/runtime/app";
6
+ import { useNitroApp } from "nitropack/runtime";
7
7
  import { parse } from "devalue";
8
8
  import { separateProps, useOgImageRuntimeConfig } from "../../shared.js";
9
9
  import { createNitroRouteRuleMatcher } from "../util/kit.js";
@@ -1,6 +1,5 @@
1
1
  import type _sharp from 'sharp';
2
2
  import type _satori from 'satori';
3
- import type _cssInline from '@css-inline/css-inline-wasm';
4
3
  export declare function useResvg(): Promise<new (svg: Uint8Array | string, options?: import("@resvg/resvg-wasm").ResvgRenderOptions) => {
5
4
  free(): void;
6
5
  render(): {
@@ -39,4 +38,4 @@ export declare function useResvg(): Promise<new (svg: Uint8Array | string, optio
39
38
  }>;
40
39
  export declare function useSatori(): Promise<typeof _satori>;
41
40
  export declare function useSharp(): Promise<typeof _sharp>;
42
- export declare function useCssInline(): Promise<typeof _cssInline>;
41
+ export declare function useCssInline(): Promise<any>;
@@ -2,6 +2,7 @@ import { withBase } from "ufo";
2
2
  import sizeOf from "image-size";
3
3
  import { defineSatoriTransformer } from "../utils.js";
4
4
  import { toBase64Image } from "../../../../pure.js";
5
+ import { logger } from "../../../util/logger.js";
5
6
  import { useNitroOrigin, useStorage } from "#imports";
6
7
  async function resolveLocalFilePathImage(publicStoragePath, src) {
7
8
  const key = `${publicStoragePath}${src.replace("./", ":").replace("/", ":")}`;
@@ -17,6 +18,9 @@ export default defineSatoriTransformer([
17
18
  const isRelative = src.startsWith("/");
18
19
  let dimensions;
19
20
  let imageBuffer;
21
+ if (src.endsWith(".webp")) {
22
+ logger.warn("Using WebP images with Satori is not supported. Please consider switching image format or use the chromium renderer.", src);
23
+ }
20
24
  if (isRelative) {
21
25
  if (import.meta.prerender || import.meta.dev) {
22
26
  imageBuffer = await resolveLocalFilePathImage(publicStoragePath, src);
@@ -1,3 +1,4 @@
1
+ import { createConsola } from "consola";
1
2
  import { useCssInline } from "../instances.js";
2
3
  import { useNitroOrigin } from "#imports";
3
4
  export async function applyInlineCss(ctx, island) {
@@ -30,6 +31,13 @@ export async function applyInlineCss(ctx, island) {
30
31
  if (!css.trim().length)
31
32
  return false;
32
33
  const cssInline = await useCssInline();
34
+ if (!cssInline || cssInline?.__unenv__) {
35
+ if (componentInlineStyles.length) {
36
+ const logger = createConsola().withTag("Nuxt OG Image");
37
+ logger.warn("To have inline styles applied you need to install either the `@css-inline/css-inline` or `@css-inline/css-inline-wasm` package.");
38
+ }
39
+ return false;
40
+ }
33
41
  html = cssInline.inline(island.html, {
34
42
  loadRemoteStylesheets: false,
35
43
  extraCss: css
@@ -1,3 +1,3 @@
1
- {
2
- "extends": "../../../.nuxt/tsconfig.server.json"
3
- }
1
+ {
2
+ "extends": "../../../.nuxt/tsconfig.server.json"
3
+ }
@@ -0,0 +1 @@
1
+ export declare const logger: import("consola").ConsolaInstance;
@@ -0,0 +1,6 @@
1
+ import { createConsola } from "consola";
2
+ export const logger = createConsola({
3
+ defaults: {
4
+ tag: "Nuxt OG Image"
5
+ }
6
+ });
@@ -1,29 +1,29 @@
1
- <script setup lang="ts">
2
- /**
3
- * @credits Full Stack Heroes <https://fullstackheroes.com/>
4
- */
5
-
6
- withDefaults(defineProps<{
7
- title?: string
8
- logo?: string
9
- }>(), {
10
- title: 'title',
11
- logo: 'https://nuxt.com/assets/design-kit/logo-white.png',
12
- })
13
- </script>
14
-
15
- <template>
16
- <div
17
- :style="{ backgroundImage: 'linear-gradient(to right, #24243e, #302b63, #0f0c29)' }"
18
- class="h-full w-full flex items-start justify-start"
19
- >
20
- <div class="flex items-start justify-start h-full">
21
- <div class="flex flex-col justify-between w-full h-full p-20">
22
- <img :src="logo" height="50">
23
- <h1 class="text-[60px] text-white font-bold text-left">
24
- {{ title }}
25
- </h1>
26
- </div>
27
- </div>
28
- </div>
29
- </template>
1
+ <script setup lang="ts">
2
+ /**
3
+ * @credits Full Stack Heroes <https://fullstackheroes.com/>
4
+ */
5
+
6
+ withDefaults(defineProps<{
7
+ title?: string
8
+ logo?: string
9
+ }>(), {
10
+ title: 'title',
11
+ logo: 'https://nuxt.com/assets/design-kit/logo-white.png',
12
+ })
13
+ </script>
14
+
15
+ <template>
16
+ <div
17
+ :style="{ backgroundImage: 'linear-gradient(to right, #24243e, #302b63, #0f0c29)' }"
18
+ class="h-full w-full flex items-start justify-start"
19
+ >
20
+ <div class="flex items-start justify-start h-full">
21
+ <div class="flex flex-col justify-between w-full h-full p-20">
22
+ <img :src="logo" height="50">
23
+ <h1 class="text-[60px] text-white font-bold text-left">
24
+ {{ title }}
25
+ </h1>
26
+ </div>
27
+ </div>
28
+ </div>
29
+ </template>
@@ -1,64 +1,64 @@
1
- <script setup lang="ts">
2
- /**
3
- * @credits @arashsheyda <https://github.com/arashsheyda>
4
- */
5
-
6
- withDefaults(defineProps<{
7
- title?: string
8
- description?: string
9
- bg?: string
10
- icon?: string
11
- logo?: string
12
- image?: string
13
- username?: string
14
- socials?: { name: string, icon: string }[]
15
- }>(), {
16
- bg: 'linear-gradient(to bottom right, #171717, #131313)',
17
- })
18
- </script>
19
-
20
- <template>
21
- <div
22
- class="relative h-full w-full flex items-center justify-center bg-neutral-900 text-white border-2 border-white"
23
- :style="{ backgroundImage: bg }"
24
- >
25
- <div
26
- v-if="image"
27
- class="absolute inset-0 w-full h-full bg-center opacity-10"
28
- :style="{ backgroundImage: `url(${image})` }"
29
- />
30
- <div class="flex flex-col items-center text-center">
31
- <h1 class="flex gap-4 text-7xl font-bold">
32
- <Icon
33
- v-if="icon"
34
- :name="icon"
35
- />
36
- {{ title }}
37
- </h1>
38
- <p class="text-2xl max-w-3xl">
39
- {{ description }}
40
- </p>
41
- </div>
42
-
43
- <img
44
- v-if="logo"
45
- :src="logo"
46
- class="absolute bottom-0 left-0 p-5"
47
- style="height: 125px; width: 153px;"
48
- >
49
- <div class="absolute bottom-5 right-5 flex gap-4">
50
- <div
51
- v-if="username"
52
- class="absolute bottom-12 right-8 font-bold"
53
- >
54
- {{ username }}
55
- </div>
56
- <Icon
57
- v-for="social of socials"
58
- :key="social.name"
59
- :name="social.icon!"
60
- class="w-7 h-7"
61
- />
62
- </div>
63
- </div>
64
- </template>
1
+ <script setup lang="ts">
2
+ /**
3
+ * @credits @arashsheyda <https://github.com/arashsheyda>
4
+ */
5
+
6
+ withDefaults(defineProps<{
7
+ title?: string
8
+ description?: string
9
+ bg?: string
10
+ icon?: string
11
+ logo?: string
12
+ image?: string
13
+ username?: string
14
+ socials?: { name: string, icon: string }[]
15
+ }>(), {
16
+ bg: 'linear-gradient(to bottom right, #171717, #131313)',
17
+ })
18
+ </script>
19
+
20
+ <template>
21
+ <div
22
+ class="relative h-full w-full flex items-center justify-center bg-neutral-900 text-white border-2 border-white"
23
+ :style="{ backgroundImage: bg }"
24
+ >
25
+ <div
26
+ v-if="image"
27
+ class="absolute inset-0 w-full h-full bg-center opacity-10"
28
+ :style="{ backgroundImage: `url(${image})` }"
29
+ />
30
+ <div class="flex flex-col items-center text-center">
31
+ <h1 class="flex gap-4 text-7xl font-bold">
32
+ <Icon
33
+ v-if="icon"
34
+ :name="icon"
35
+ />
36
+ {{ title }}
37
+ </h1>
38
+ <p class="text-2xl max-w-3xl">
39
+ {{ description }}
40
+ </p>
41
+ </div>
42
+
43
+ <img
44
+ v-if="logo"
45
+ :src="logo"
46
+ class="absolute bottom-0 left-0 p-5"
47
+ style="height: 125px; width: 153px;"
48
+ >
49
+ <div class="absolute bottom-5 right-5 flex gap-4">
50
+ <div
51
+ v-if="username"
52
+ class="absolute bottom-12 right-8 font-bold"
53
+ >
54
+ {{ username }}
55
+ </div>
56
+ <Icon
57
+ v-for="social of socials"
58
+ :key="social.name"
59
+ :name="social.icon!"
60
+ class="w-7 h-7"
61
+ />
62
+ </div>
63
+ </div>
64
+ </template>