@@ -12,7 +12,7 @@ import { useLocalStorage, useWindowSize } from '@vueuse/core'
12
12
import defu from ' defu'
13
13
import JsonEditorVue from ' json-editor-vue'
14
14
import { Pane , Splitpanes } from ' splitpanes'
15
- import { joinURL , parseURL , withHttps , withQuery } from ' ufo'
15
+ import { hasProtocol , joinURL , parseURL , withHttps , withQuery } from ' ufo'
16
16
import { ref } from ' vue'
17
17
import { fetchGlobalDebug } from ' ~/composables/fetch'
18
18
import { devtoolsClient } from ' ~/composables/rpc'
@@ -42,20 +42,13 @@ await loadShiki()
42
42
43
43
const { data : globalDebug } = fetchGlobalDebug ()
44
44
45
- // const clientPath = computed(() => devtoolsClient.value?.host.nuxt.vueApp.config?.globalProperties?.$route?.path || undefined)
46
- // path.value = clientPath.value || useRoute().query.path as string || '/'
47
- // base.value = useRoute().query.base as string || '/'
48
- // watch(() => clientPath, (v) => {
49
- // optionsOverrides.value = {}
50
- // propsEdited.value = false
51
- // path.value = v
52
- // })
53
-
54
45
const emojis = ref (' noto' )
55
46
56
47
const debugAsyncData = fetchPathDebug ()
57
48
const { data : debug, pending, error } = debugAsyncData
58
-
49
+ const isCustomOgImage = computed (() => {
50
+ return debug .value ?.custom
51
+ })
59
52
watch (debug , (val ) => {
60
53
if (! val )
61
54
return
@@ -127,6 +120,12 @@ const src = computed(() => {
127
120
// wait until we know what we're rendering
128
121
if (! debug .value )
129
122
return ' '
123
+ if (isCustomOgImage .value ) {
124
+ if (hasProtocol (debug .value .options .url , { acceptRelative: true })) {
125
+ return debug .value .options .url
126
+ }
127
+ return joinURL (host .value , debug .value .options .url )
128
+ }
130
129
return withQuery (joinURL (host .value , ' /__og-image__/image' , path .value , ` /og.${imageFormat .value } ` ), {
131
130
timestamp: refreshTime .value ,
132
131
... optionsOverrides .value ,
@@ -148,7 +147,11 @@ const socialPreviewDescription = computed(() => {
148
147
149
148
const socialSiteUrl = computed (() => {
150
149
// need to turn this URL into just an origin
151
- return parseURL (debug .value ?.siteConfig ?.url || ' /' ).host || debug .value ?.siteConfig ?.url || ' /'
150
+ const url = parseURL (debug .value ?.siteConfig ?.url || ' /' ).host || debug .value ?.siteConfig ?.url || ' /'
151
+ if (url === ' /' ) {
152
+ return globalDebug .value ?.siteConfigUrl
153
+ }
154
+ return url
152
155
})
153
156
const slackSocialPreviewSiteName = computed (() => {
154
157
return options .value ?.socialPreview ?.og .site_name || socialSiteUrl .value
@@ -375,7 +378,60 @@ const currentPageFile = computed(() => {
375
378
<div class =" flex-row flex p4 h-full" style =" min-height : calc (100vh - 64px );" >
376
379
<main class =" mx-auto flex flex-col w-full" >
377
380
<div v-if =" tab === 'design'" class =" h-full relative max-h-full" >
378
- <div v-if =" error" >
381
+ <div v-if =" isCustomOgImage" class =" w-full flex h-full justify-center items-center relative pr-4" style =" padding-top : 30px ;" >
382
+ <div class =" flex justify-between items-center text-sm w-full absolute pr-[30px] top-0 left-0" >
383
+ <div class =" text-xs" >
384
+ Your prebuilt OG Image: {{ debug?.options.url }}
385
+ </div >
386
+ <div class =" flex items-center w-[100px]" >
387
+ <NButton icon =" carbon:drag-horizontal" :border =" !socialPreview" @click =" toggleSocialPreview()" />
388
+ <NButton icon =" logos:twitter" :border =" socialPreview === 'twitter'" @click =" toggleSocialPreview('twitter')" />
389
+ <NButton icon =" logos:slack-icon" :border =" socialPreview === 'slack'" @click =" toggleSocialPreview('slack')" />
390
+ </div >
391
+ </div >
392
+ <TwitterCardRenderer v-if =" socialPreview === 'twitter'" :title =" socialPreviewTitle" >
393
+ <template #domain >
394
+ <a target =" _blank" :href =" withHttps(socialSiteUrl)" >From {{ socialSiteUrl }}</a >
395
+ </template >
396
+ <ImageLoader
397
+ :src =" src"
398
+ :aspect-ratio =" aspectRatio"
399
+ @load =" generateLoadTime"
400
+ @click =" openImage"
401
+ @refresh =" refreshSources"
402
+ />
403
+ </TwitterCardRenderer >
404
+ <SlackCardRenderer v-else-if =" socialPreview === 'slack'" >
405
+ <template #favIcon >
406
+ <img :src =" `https://www.google.com/s2/favicons?domain=${encodeURIComponent(socialSiteUrl)}&sz=30`" >
407
+ </template >
408
+ <template #siteName >
409
+ {{ slackSocialPreviewSiteName }}
410
+ </template >
411
+ <template #title >
412
+ {{ socialPreviewTitle }}
413
+ </template >
414
+ <template #description >
415
+ {{ socialPreviewDescription }}
416
+ </template >
417
+ <ImageLoader
418
+ :src =" src"
419
+ class =" !h-[300px]"
420
+ :aspect-ratio =" aspectRatio"
421
+ @load =" generateLoadTime"
422
+ @refresh =" refreshSources"
423
+ />
424
+ </SlackCardRenderer >
425
+ <div v-else class =" w-full h-full" >
426
+ <ImageLoader
427
+ :src =" src"
428
+ :aspect-ratio =" aspectRatio"
429
+ @load =" generateLoadTime"
430
+ @refresh =" refreshSources"
431
+ />
432
+ </div >
433
+ </div >
434
+ <div v-else-if =" error" >
379
435
<div v-if =" error.message.includes('missing the Nuxt OG Image payload') || error.message.includes('Got invalid response')" >
380
436
<!-- nicely tell the user they should use defineOgImage to get started -->
381
437
<div class =" flex flex-col items-center justify-center mx-auto max-w-135 h-85vh" >
@@ -460,7 +516,7 @@ const currentPageFile = computed(() => {
460
516
</TwitterCardRenderer >
461
517
<SlackCardRenderer v-else-if =" socialPreview === 'slack'" >
462
518
<template #favIcon >
463
- <img :src =" `${socialSiteUrl?.includes('localhost') ? 'http' : ' https'} ://${ socialSiteUrl}/favicon.ico `" >
519
+ <img :src =" `https://www.google.com/s2/favicons?domain=${encodeURIComponent( socialSiteUrl)}&sz=30 `" >
464
520
</template >
465
521
<template #siteName >
466
522
{{ slackSocialPreviewSiteName }}
0 commit comments