diff --git a/site/app/composables/usePageSeo.ts b/site/app/composables/usePageSeo.ts new file mode 100644 index 0000000..511f807 --- /dev/null +++ b/site/app/composables/usePageSeo.ts @@ -0,0 +1,37 @@ +const DEFAULT_DESCRIPTION = + 'AutoFixture makes unit tests more productive by creating anonymous test data for .NET.' + +const DEFAULT_OG_IMAGE = '/og-image.png' + +type PageSeoOptions = { + title?: MaybeRefOrGetter + description?: MaybeRefOrGetter + image?: MaybeRefOrGetter +} + +export function usePageSeo(options: PageSeoOptions = {}) { + const route = useRoute() + const { public: { siteUrl } } = useRuntimeConfig() + + const title = computed(() => toValue(options.title) ?? 'AutoFixture') + const description = computed(() => toValue(options.description) ?? DEFAULT_DESCRIPTION) + const image = computed(() => `${siteUrl}${toValue(options.image) ?? DEFAULT_OG_IMAGE}`) + const url = computed(() => `${siteUrl}${route.path}`) + + useHead({ + title, + meta: computed(() => [ + { name: 'description', content: description.value }, + { property: 'og:title', content: title.value }, + { property: 'og:description', content: description.value }, + { property: 'og:image', content: image.value }, + { property: 'og:url', content: url.value }, + { property: 'og:type', content: 'website' }, + { property: 'og:site_name', content: 'AutoFixture' }, + { name: 'twitter:card', content: 'summary_large_image' }, + { name: 'twitter:title', content: title.value }, + { name: 'twitter:description', content: description.value }, + { name: 'twitter:image', content: image.value }, + ]), + }) +} diff --git a/site/app/pages/api/[...slug].vue b/site/app/pages/api/[...slug].vue index c6c4dcd..bc0d38c 100644 --- a/site/app/pages/api/[...slug].vue +++ b/site/app/pages/api/[...slug].vue @@ -62,8 +62,9 @@ if (!page.value) { const pageTitle = computed(() => page.value?.title ?? 'API') const tocLinks = computed(() => page.value?.tocLinks ?? []) -useSeoMeta({ +usePageSeo({ title: () => pageTitle.value, + description: () => `AutoFixture API reference — ${pageTitle.value}`, }) diff --git a/site/app/pages/docs/[...slug].vue b/site/app/pages/docs/[...slug].vue index bc0be63..51b34ea 100644 --- a/site/app/pages/docs/[...slug].vue +++ b/site/app/pages/docs/[...slug].vue @@ -20,9 +20,9 @@ const { data: surround } = await useAsyncData( () => queryCollectionItemSurroundings('docs', docsPath.value), ) -useSeoMeta({ - title: page.value.title, - description: page.value.description, +usePageSeo({ + title: () => page.value?.title, + description: () => page.value?.description, }) const tocLinks = computed(() => page.value?.body?.toc?.links ?? []) diff --git a/site/app/pages/index.vue b/site/app/pages/index.vue index 43d2e0c..8060f31 100644 --- a/site/app/pages/index.vue +++ b/site/app/pages/index.vue @@ -1,7 +1,7 @@