Skip to content

Commit

Permalink
fix(content): strictNuxtContentPaths config
Browse files Browse the repository at this point in the history
  • Loading branch information
harlan-zw committed Sep 11, 2024
1 parent f21844c commit 2b7c611
Show file tree
Hide file tree
Showing 10 changed files with 260 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -204,4 +204,3 @@ Thanks for following along! You know have a basic understanding of how to use th
It's recommended to look through the rest of the documentation to get a full understanding of what's possible.

If you have any questions, feel free to reach out on [Discord](https://discord.gg/8NjyQJrZ) or [GitHub](https://github.com/harlan-zw/nuxt-og-image).

20 changes: 20 additions & 0 deletions docs/content/1.integrations/1.content.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,26 @@ ogImage:
---
```

If you're not using `documentDriven` mode and all of your content paths are the same as their real paths,
you can enable `strictNuxtContentPaths` to get the same behaviour.

```ts [nuxt.config.ts]
export default defineNuxtConfig({
ogImage: {
strictNuxtContentPaths: true
}
})
```

Additionally, you will need to make sure you're using the `useContentHead` composable if you're not using Document Driven mode.

```vue [[...slug].vue]
<script setup>
const page = await useAsyncData(`docs-${route.path}`, () => queryContent(route.path).findOne())
useContentHead(page)
</script>
```

### Using Components

If you'd like to use the `<OgImage />` or `<OgImageScreenshot />` components within your content instead of using
Expand Down
8 changes: 8 additions & 0 deletions docs/content/4.api/3.config.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,14 @@ export default defineNuxtConfig({
})
```

## `strictNuxtContentPaths`

- Type: `boolean`
- Default: `false`

Whether the paths within nuxt/content match their real paths. This is useful when you're using the `nuxt/content` module
without documentDriven mode.

### `debug`

- Type: `boolean`
Expand Down
11 changes: 10 additions & 1 deletion src/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,15 @@ export interface ModuleOptions {
* Only allow the prerendering and dev runtimes to generate images.
*/
zeroRuntime?: boolean

/**
* Enable when your nuxt/content files match your pages.
*
* This will automatically map the `ogImage` frontmatter key to the correct path.
*
* This is similar behavior to using `nuxt/content` with `documentDriven: true`.
*/
strictNuxtContentPaths: boolean
}

export interface ModuleHooks {
Expand Down Expand Up @@ -586,7 +595,7 @@ declare module '#nuxt-og-image/unocss-config' {
colorPreference,

// @ts-expect-error runtime type
isNuxtContentDocumentDriven: !!nuxt.options.content?.documentDriven,
isNuxtContentDocumentDriven: config.strictNuxtContentPaths || !!nuxt.options.content?.documentDriven,
}
// @ts-expect-error untyped
nuxt.hooks.callHook('nuxt-og-image:runtime-config', runtimeConfig)
Expand Down
6 changes: 5 additions & 1 deletion src/runtime/nitro/og-image/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@ import { separateProps, useOgImageRuntimeConfig } from '../../shared'
import { decodeObjectHtmlEntities } from '../util/encoding'
import { createNitroRouteRuleMatcher } from '../util/kit'
import { useChromiumRenderer, useSatoriRenderer } from './instances'
import type { OgImageOptions, OgImageRenderEventContext, SocialPreviewMetaData } from '../../types'
import type {
OgImageOptions,
OgImageRenderEventContext,
SocialPreviewMetaData,
} from '../../types'
import type ChromiumRenderer from './chromium/renderer'
import type SatoriRenderer from './satori/renderer'

Expand Down
2 changes: 1 addition & 1 deletion src/runtime/nitro/util/plugins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export function nuxtContentPlugin(nitroApp: NitroApp) {
return

let path = content.path
if (isNuxtContentDocumentDriven)
if (isNuxtContentDocumentDriven && content.path)
path = content._path
// convert ogImage to head tags
if (path && content.ogImage) {
Expand Down
100 changes: 100 additions & 0 deletions test/fixtures/content/components/OgImage/NuxtSeo.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
<script setup lang="ts">
import { computed } from 'vue'
// convert to typescript props
const props = withDefaults(defineProps<{
colorMode?: 'dark' | 'light'
title?: string
description?: string
icon?: string | boolean
version?: string
moduleName?: string
theme?: string
}>(), {
colorMode: 'light',
theme: '#00dc82',
title: 'title',
})
const HexRegex = /^#(?:[0-9a-f]{3}){1,2}$/i
const themeHex = computed(() => {
// regex test if valid hex
if (HexRegex.test(props.theme))
return props.theme
// if it's hex without the hash, just add the hash
if (HexRegex.test(`#${props.theme}`))
return `#${props.theme}`
// if it's rgb or rgba, we convert it to hex
if (props.theme.startsWith('rgb')) {
const rgb = props.theme
.replace('rgb(', '')
.replace('rgba(', '')
.replace(')', '')
.split(',')
.map(v => Number.parseInt(v.trim(), 10))
const hex = rgb
.map((v) => {
const hex = v.toString(16)
return hex.length === 1 ? `0${hex}` : hex
})
.join('')
return `#${hex}`
}
return '#FFFFFF'
})
const themeRgb = computed(() => {
// we want to convert it so it's just `<red>, <green>, <blue>` (255, 255, 255)
return themeHex.value
.replace('#', '')
.match(/.{1,2}/g)
?.map(v => Number.parseInt(v, 16))
.join(', ')
})
</script>

<template>
<div
class="w-full h-full flex justify-between relative p-[60px]"
:class="[
colorMode === 'light' ? ['bg-white', 'text-gray-900'] : ['bg-gray-900', 'text-gray-50'],
]"
>
<div
class="flex absolute right-[-110%]" :style="{
width: '200%',
height: '250%',
backgroundImage: `radial-gradient(circle, rgba(${themeRgb}, 0.5) 0%, ${colorMode === 'dark' ? 'rgba(5, 5, 5,0.3)' : 'rgba(255, 255, 255, 0.7)'} 50%, ${props.colorMode === 'dark' ? 'rgba(5, 5, 5,0)' : 'rgba(255, 255, 255, 0)'} 70%)`,
}"
/>
<div class="h-full w-full relative">
<div class="flex flex-row justify-between items-center">
<div class="flex flex-row items-center">
<svg height="50" viewBox="0 0 1204 200" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M377 200C379.16 200 381 198.209 381 196V103C381 103 386 112 395 127L434 194C435.785 197.74 439.744 200 443 200H470V50H443C441.202 50 439 51.4941 439 54V148L421 116L385 55C383.248 51.8912 379.479 50 376 50H350V200H377Z" fill="currentColor" />
<path d="M726 92H739C742.314 92 745 89.3137 745 86V60H773V92H800V116H773V159C773 169.5 778.057 174 787 174H800V200H783C759.948 200 745 185.071 745 160V116H726V92Z" fill="currentColor" />
<path d="M591 92V154C591 168.004 585.742 179.809 578 188C570.258 196.191 559.566 200 545 200C530.434 200 518.742 196.191 511 188C503.389 179.809 498 168.004 498 154V92H514C517.412 92 520.769 92.622 523 95C525.231 97.2459 526 98.5652 526 102V154C526 162.059 526.457 167.037 530 171C533.543 174.831 537.914 176 545 176C552.217 176 555.457 174.831 559 171C562.543 167.037 563 162.059 563 154V102C563 98.5652 563.769 96.378 566 94C567.96 91.9107 570.028 91.9599 573 92C573.411 92.0055 574.586 92 575 92H591Z" fill="currentColor" />
<path d="M676 144L710 92H684C680.723 92 677.812 93.1758 676 96L660 120L645 97C643.188 94.1758 639.277 92 636 92H611L645 143L608 200H634C637.25 200 640.182 196.787 642 194L660 167L679 195C680.818 197.787 683.75 200 687 200H713L676 144Z" fill="currentColor" />
<path d="M168 200H279C282.542 200 285.932 198.756 289 197C292.068 195.244 295.23 193.041 297 190C298.77 186.959 300.002 183.51 300 179.999C299.998 176.488 298.773 173.04 297 170.001L222 41C220.23 37.96 218.067 35.7552 215 34C211.933 32.2448 207.542 31 204 31C200.458 31 197.067 32.2448 194 34C190.933 35.7552 188.77 37.96 187 41L168 74L130 9.99764C128.228 6.95784 126.068 3.75491 123 2C119.932 0.245087 116.542 0 113 0C109.458 0 106.068 0.245087 103 2C99.9323 3.75491 96.7717 6.95784 95 9.99764L2 170.001C0.226979 173.04 0.00154312 176.488 1.90993e-06 179.999C-0.0015393 183.51 0.229648 186.959 2 190C3.77035 193.04 6.93245 195.244 10 197C13.0675 198.756 16.4578 200 20 200H90C117.737 200 137.925 187.558 152 164L186 105L204 74L259 168H186L168 200ZM89 168H40L113 42L150 105L125.491 147.725C116.144 163.01 105.488 168 89 168Z" fill="#00DC82" />
<path d="M892 200C881.746 200 873.788 197.911 866 194C858.212 189.959 851.543 184.169 847 177C842.587 169.7 840.389 161.646 840 152H868C868.649 159.039 870.717 163.959 875 168C879.413 172.041 885.861 174 893 174C899.62 174 904.106 172.737 908 170C912.024 167.263 914 164.084 914 159C914 155.48 913.336 152.086 911 150C908.793 147.784 906.375 146.173 903 145C899.625 143.827 894.23 142.564 888 141C878.784 138.784 870.971 136.477 865 134C859.159 131.393 854.283 127.605 850 122C845.717 116.395 844 108.777 844 99C844 91.5698 845.976 84.8659 850 79C854.024 73.1341 859.861 68.2589 867 65C874.139 61.6108 881.914 60 891 60C900.735 60 909.601 61.4805 917 65C924.528 68.5196 929.846 73.4823 934 80C938.283 86.5177 940.74 94.3967 941 103H913C912.481 97.5251 910.894 93.1285 907 90C903.106 86.7411 897.49 85 891 85C885.289 85 880.375 86.5233 877 89C873.625 91.4767 872 94.959 872 99C872 102.78 873.664 105.784 876 108C878.336 110.216 881.366 111.696 885 113C888.634 114.173 893.64 115.566 900 117C909.346 119.216 916.159 121.654 922 124C927.841 126.346 932.846 130.395 937 136C941.283 141.475 944 148.354 944 158C944 166.473 941.283 173.743 937 180C932.717 186.257 926.788 191.611 919 195C911.342 198.389 902.124 200 892 200Z" fill="#00DC82" />
<path d="M1056 200H961V60H1054V87H990V116H1041V141H990V173H1056V200Z" fill="#00DC82" />
<path d="M1134 200C1120.76 200 1108.64 196.996 1098 191C1087.49 184.873 1080.1 176.559 1074 166C1068.03 155.311 1065 143.296 1065 130C1065 116.704 1068.03 104.559 1074 94C1080.1 83.311 1088.49 74.9963 1099 69C1109.64 62.8734 1120.76 60 1134 60C1147.11 60 1159.49 62.8734 1170 69C1180.64 74.9963 1189.03 83.311 1195 94C1201.1 104.559 1204 116.704 1204 130C1204 143.296 1201.1 155.311 1195 166C1189.03 176.559 1180.64 184.873 1170 191C1159.49 196.996 1147.11 200 1134 200ZM1134 174C1141.66 174 1148.9 172.78 1155 169C1161.23 165.089 1165.63 159.778 1169 153C1172.5 146.222 1174 138.473 1174 130C1174 121.527 1172.5 113.778 1169 107C1165.63 100.222 1161.23 94.9106 1155 91C1148.9 87.0894 1141.66 85 1134 85C1126.34 85 1120.1 87.0894 1114 91C1107.9 94.9106 1102.5 100.222 1099 107C1095.63 113.778 1094 121.527 1094 130C1094 138.473 1095.63 146.222 1099 153C1102.5 159.778 1107.9 165.089 1114 169C1120.1 172.78 1126.34 174 1134 174Z" fill="#00DC82" />
</svg>
</div>
</div>
<div class="flex-grow flex items-center justify-start">
<div class="max-w-[800px] flex justify-center gap-7 flex-col">
<h1 class="text-[60px] max-w-[700px] font-bold m-0">
{{ title }}
</h1>
<p class="text-[32px] leading-[45px] max-w-[800px] opacity-90 font-normal m-0">
{{ description }}
</p>
</div>
</div>
</div>
</div>
</template>
100 changes: 100 additions & 0 deletions test/fixtures/content/components/OgImage/Release.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
<script setup lang="ts">
import { computed } from 'vue'
// convert to typescript props
const props = withDefaults(defineProps<{
colorMode?: 'dark' | 'light'
title?: string
description?: string
icon?: string | boolean
version?: string
moduleName?: string
theme?: string
}>(), {
colorMode: 'light',
theme: '#00dc82',
title: 'title',
})
const HexRegex = /^#(?:[0-9a-f]{3}){1,2}$/i
const themeHex = computed(() => {
// regex test if valid hex
if (HexRegex.test(props.theme))
return props.theme
// if it's hex without the hash, just add the hash
if (HexRegex.test(`#${props.theme}`))
return `#${props.theme}`
// if it's rgb or rgba, we convert it to hex
if (props.theme.startsWith('rgb')) {
const rgb = props.theme
.replace('rgb(', '')
.replace('rgba(', '')
.replace(')', '')
.split(',')
.map(v => Number.parseInt(v.trim(), 10))
const hex = rgb
.map((v) => {
const hex = v.toString(16)
return hex.length === 1 ? `0${hex}` : hex
})
.join('')
return `#${hex}`
}
return '#FFFFFF'
})
const themeRgb = computed(() => {
// we want to convert it so it's just `<red>, <green>, <blue>` (255, 255, 255)
return themeHex.value
.replace('#', '')
.match(/.{1,2}/g)
?.map(v => Number.parseInt(v, 16))
.join(', ')
})
</script>

<template>
<div
class="w-full h-full flex justify-between relative p-[60px]"
:class="[
colorMode === 'light' ? ['bg-white', 'text-gray-900'] : ['bg-gray-900', 'text-gray-50'],
]"
>
<div
class="flex absolute right-[-110%]" :style="{
width: '200%',
height: '250%',
backgroundImage: `radial-gradient(circle, rgba(${themeRgb}, 0.5) 0%, ${colorMode === 'dark' ? 'rgba(5, 5, 5,0.3)' : 'rgba(255, 255, 255, 0.7)'} 50%, ${props.colorMode === 'dark' ? 'rgba(5, 5, 5,0)' : 'rgba(255, 255, 255, 0)'} 70%)`,
}"
/>
<div class="h-full w-full relative">
<div class="flex flex-row justify-between items-center">
<div class="flex flex-row items-center">
<svg height="50" viewBox="0 0 1204 200" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M377 200C379.16 200 381 198.209 381 196V103C381 103 386 112 395 127L434 194C435.785 197.74 439.744 200 443 200H470V50H443C441.202 50 439 51.4941 439 54V148L421 116L385 55C383.248 51.8912 379.479 50 376 50H350V200H377Z" fill="currentColor" />
<path d="M726 92H739C742.314 92 745 89.3137 745 86V60H773V92H800V116H773V159C773 169.5 778.057 174 787 174H800V200H783C759.948 200 745 185.071 745 160V116H726V92Z" fill="currentColor" />
<path d="M591 92V154C591 168.004 585.742 179.809 578 188C570.258 196.191 559.566 200 545 200C530.434 200 518.742 196.191 511 188C503.389 179.809 498 168.004 498 154V92H514C517.412 92 520.769 92.622 523 95C525.231 97.2459 526 98.5652 526 102V154C526 162.059 526.457 167.037 530 171C533.543 174.831 537.914 176 545 176C552.217 176 555.457 174.831 559 171C562.543 167.037 563 162.059 563 154V102C563 98.5652 563.769 96.378 566 94C567.96 91.9107 570.028 91.9599 573 92C573.411 92.0055 574.586 92 575 92H591Z" fill="currentColor" />
<path d="M676 144L710 92H684C680.723 92 677.812 93.1758 676 96L660 120L645 97C643.188 94.1758 639.277 92 636 92H611L645 143L608 200H634C637.25 200 640.182 196.787 642 194L660 167L679 195C680.818 197.787 683.75 200 687 200H713L676 144Z" fill="currentColor" />
<path d="M168 200H279C282.542 200 285.932 198.756 289 197C292.068 195.244 295.23 193.041 297 190C298.77 186.959 300.002 183.51 300 179.999C299.998 176.488 298.773 173.04 297 170.001L222 41C220.23 37.96 218.067 35.7552 215 34C211.933 32.2448 207.542 31 204 31C200.458 31 197.067 32.2448 194 34C190.933 35.7552 188.77 37.96 187 41L168 74L130 9.99764C128.228 6.95784 126.068 3.75491 123 2C119.932 0.245087 116.542 0 113 0C109.458 0 106.068 0.245087 103 2C99.9323 3.75491 96.7717 6.95784 95 9.99764L2 170.001C0.226979 173.04 0.00154312 176.488 1.90993e-06 179.999C-0.0015393 183.51 0.229648 186.959 2 190C3.77035 193.04 6.93245 195.244 10 197C13.0675 198.756 16.4578 200 20 200H90C117.737 200 137.925 187.558 152 164L186 105L204 74L259 168H186L168 200ZM89 168H40L113 42L150 105L125.491 147.725C116.144 163.01 105.488 168 89 168Z" fill="#00DC82" />
<path d="M892 200C881.746 200 873.788 197.911 866 194C858.212 189.959 851.543 184.169 847 177C842.587 169.7 840.389 161.646 840 152H868C868.649 159.039 870.717 163.959 875 168C879.413 172.041 885.861 174 893 174C899.62 174 904.106 172.737 908 170C912.024 167.263 914 164.084 914 159C914 155.48 913.336 152.086 911 150C908.793 147.784 906.375 146.173 903 145C899.625 143.827 894.23 142.564 888 141C878.784 138.784 870.971 136.477 865 134C859.159 131.393 854.283 127.605 850 122C845.717 116.395 844 108.777 844 99C844 91.5698 845.976 84.8659 850 79C854.024 73.1341 859.861 68.2589 867 65C874.139 61.6108 881.914 60 891 60C900.735 60 909.601 61.4805 917 65C924.528 68.5196 929.846 73.4823 934 80C938.283 86.5177 940.74 94.3967 941 103H913C912.481 97.5251 910.894 93.1285 907 90C903.106 86.7411 897.49 85 891 85C885.289 85 880.375 86.5233 877 89C873.625 91.4767 872 94.959 872 99C872 102.78 873.664 105.784 876 108C878.336 110.216 881.366 111.696 885 113C888.634 114.173 893.64 115.566 900 117C909.346 119.216 916.159 121.654 922 124C927.841 126.346 932.846 130.395 937 136C941.283 141.475 944 148.354 944 158C944 166.473 941.283 173.743 937 180C932.717 186.257 926.788 191.611 919 195C911.342 198.389 902.124 200 892 200Z" fill="#00DC82" />
<path d="M1056 200H961V60H1054V87H990V116H1041V141H990V173H1056V200Z" fill="#00DC82" />
<path d="M1134 200C1120.76 200 1108.64 196.996 1098 191C1087.49 184.873 1080.1 176.559 1074 166C1068.03 155.311 1065 143.296 1065 130C1065 116.704 1068.03 104.559 1074 94C1080.1 83.311 1088.49 74.9963 1099 69C1109.64 62.8734 1120.76 60 1134 60C1147.11 60 1159.49 62.8734 1170 69C1180.64 74.9963 1189.03 83.311 1195 94C1201.1 104.559 1204 116.704 1204 130C1204 143.296 1201.1 155.311 1195 166C1189.03 176.559 1180.64 184.873 1170 191C1159.49 196.996 1147.11 200 1134 200ZM1134 174C1141.66 174 1148.9 172.78 1155 169C1161.23 165.089 1165.63 159.778 1169 153C1172.5 146.222 1174 138.473 1174 130C1174 121.527 1172.5 113.778 1169 107C1165.63 100.222 1161.23 94.9106 1155 91C1148.9 87.0894 1141.66 85 1134 85C1126.34 85 1120.1 87.0894 1114 91C1107.9 94.9106 1102.5 100.222 1099 107C1095.63 113.778 1094 121.527 1094 130C1094 138.473 1095.63 146.222 1099 153C1102.5 159.778 1107.9 165.089 1114 169C1120.1 172.78 1126.34 174 1134 174Z" fill="#00DC82" />
</svg>
</div>
</div>
<div class="flex-grow flex items-center justify-start">
<div class="max-w-[800px] flex justify-center gap-7 flex-col">
<h1 class="text-[60px] max-w-[700px] font-bold m-0">
{{ title }}
</h1>
<p class="text-[32px] leading-[45px] max-w-[800px] opacity-90 font-normal m-0">
{{ description }}
</p>
</div>
</div>
</div>
</div>
</template>
14 changes: 11 additions & 3 deletions test/fixtures/content/content/index.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
---
path: '/'
title: 'Nuxt Content'
title: Nuxt OG Image v3
description: Release notes for Nuxt OG Image v3.
path: /og-image/releases/v3
publishedOn: 2023-12-11
navigation:
title: v3.0.0
ogImage:
description: 'Hello OG Image'
component: Release
props:
title: Nuxt OG Image v3 ✨
colorScheme: dark
description: Nuxt OG Image v3 is here, and it's a complete rewrite of the module to improve stability and DX. I think you're going to love it!
---

# bar
6 changes: 5 additions & 1 deletion test/fixtures/content/nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,16 @@ export default defineNuxtConfig({
NuxtOgImage,
'@nuxt/content',
],

site: {
url: 'https://nuxtseo.com',
},

ogImage: {
debug: true,
},
devtools: { enabled: false },

devtools: { enabled: true },
debug: process.env.NODE_ENV === 'test',
compatibilityDate: '2024-09-11',
})

0 comments on commit 2b7c611

Please sign in to comment.