Skip to content

Commit 96b76f9

Browse files
authored
[DO-563] Implement open graph protocol meta tags customization (#49)
* Define meta information as computed * Generate open graph title * Generate open graph description * Declare global baseUrl option * Define sitename and URL tags * Specify default open graph description * Fix title template bug * Update docs
1 parent 419af6f commit 96b76f9

File tree

8 files changed

+79
-25
lines changed

8 files changed

+79
-25
lines changed

app.vue

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,21 @@
1515
-->
1616

1717
<script setup>
18-
const config = useAppConfig().exactproDocs
18+
import { resolveURL } from 'ufo'
19+
const config = useToolkitConfig()
20+
21+
const siteDescription = config?.seo?.description ?? null
1922
2023
useSeoMeta({
2124
titleTemplate: (title) => {
2225
if (title) return `${title} | ${config.title}`
23-
return title
26+
return config.title
2427
},
25-
description: config?.seo?.description ?? null,
26-
generator: '@exactpro/docs-web-toolkit'
28+
description: siteDescription,
29+
ogDescription: siteDescription,
30+
generator: '@exactpro/docs-web-toolkit',
31+
ogSiteName: config.title,
32+
ogUrl: computed(() => resolveURL(config.seo.baseUrl, useRoute().path))
2733
})
2834
2935
useHead({

components/ep/PageMeta.vue

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,22 +17,27 @@
1717
<script setup lang="ts">
1818
import { ParsedContent } from '@nuxt/content/dist/runtime/types'
1919
20-
defineProps<{
20+
const props = defineProps<{
2121
doc: Pick<ParsedContent, string> | null
2222
}>()
2323
24+
const title = computed<string>(() => props.doc?.title ?? '')
25+
const description = computed<string>(() => props.doc?.description ?? '')
26+
2427
const config = useAppConfig()
2528
const verificationMetaTags = config.exactproDocs.seo?.verificationMetaTags
2629
</script>
2730

2831
<template>
2932
<Head>
30-
<Title>{{ doc ? doc.title : '' }}</Title>
31-
<Meta
32-
v-if="doc && doc.description"
33-
name="description"
34-
:content="doc.description"
35-
/>
33+
<template v-if="title">
34+
<Title>{{ title }}</Title>
35+
<Meta property="og:title" :content="title" />
36+
</template>
37+
<template v-if="description">
38+
<Meta name="description" :content="description" />
39+
<Meta property="og:description" :content="description" />
40+
</template>
3641
<Meta
3742
v-for="(verification, index) of verificationMetaTags"
3843
:key="index"

composables/config.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* Copyright 2023 Exactpro (Exactpro Systems Limited)
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import { defu } from 'defu'
18+
import type { CustomAppConfig } from '../.nuxt/schema/nuxt.schema'
19+
20+
type ToolkitConfig = NonNullable<CustomAppConfig['exactproDocs']>
21+
22+
export function useToolkitConfig(): ToolkitConfig {
23+
const appConfig = useAppConfig()
24+
const docsConfig = appConfig.exactproDocs
25+
const computedDefaultValues: ToolkitConfig = {
26+
seo: {
27+
sitemap: {
28+
baseUrl: docsConfig.seo?.baseUrl
29+
}
30+
}
31+
}
32+
return defu(docsConfig, computedDefaultValues)
33+
}

docs/app.config.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,9 @@ export default defineAppConfig({
3131
seo: {
3232
description:
3333
'Documentation toolkit for Exactpro projects powered by Nuxt.js',
34+
baseUrl: 'https://exactpro.github.io/docs-toolkit',
3435
keywords: ['documentation', 'nuxt3', 'nuxt.js', 'vue.js', 'exactpro'],
3536
robots: [{ UserAgent: '*' }, { Allow: '/' }],
36-
sitemap: {
37-
baseUrl: 'https://exactpro.github.io/docs-toolkit'
38-
},
3937
verificationMetaTags: [
4038
// <meta name="google-site-verification" content="PYzR06VK4UIZvGdBkMh_TkqOu83QxapFJknyAR58yJA" />
4139
{

docs/content/2.features/5.seo.md

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ export default defineAppConfig({
1414
seo: {
1515
description:
1616
'1-2 sentences to briefly describe content of your website',
17+
baseUrl: 'default base URL of your website'
1718
keywords: ['keyword1', 'keyword2', 'keyword3'],
1819
robots: [{ UserAgent: '*' }, { Allow: '/' }],
1920
sitemap: {
20-
baseUrl: 'base URL of your website'
21+
baseUrl: 'base URL of your website specified for sitemap'
2122
},
2223
verificationMetaTags: [
23-
// <meta name="google-search-console-token" />
2424
{
2525
name: 'google-site-verification',
2626
content: 'google-search-console-token'
@@ -56,11 +56,9 @@ You can use `app.config.ts` of our documentation as another example of SEO confi
5656
| Option | Type | Description |
5757
| --- |----------|----------------------------------------------------------------------------------------------------------------------------------------------|
5858
| `description` | `string` | Provide 1-2 sentences to briefly describe content of your website. They will be displayed under the link to your website in search results. |
59+
| `baseUrl` | `string` | Default base URL for SEO properties. It will be used as a default value for sitemap, robots.txt, and Open Graph tags. |
5960
| `keywords` | `array` | Here you should pass all keywords that describes your website as an array, they will be used to characterise your website for search engine. |
6061
| `robots` | `array` | Configuration for `robots.txt`. See [the page](https://github.com/nuxt-modules/) to see more details and examples of available features. |
6162
| `sitemap.baseUrl` | `string` | Base URL for sitemap. All links in sitemap will be relative to this URL. |
6263
| `verificationMetaTags` | `array` | Here you should specify name and content of meta tag, that required for verification of your resource in some search engine. See [the page](https://support.google.com/webmasters/answer/9008080?hl=en#meta_tag_verification) about verification meta tags configuration for Google search engine. |
63-
| `verificationMetaTags.content` | `string` | Specify content of meta tag as search resource required. |
64-
65-
6664

nuxt.schema.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,16 @@ export default defineNuxtSchema({
9090
type: 'string'
9191
}
9292
},
93+
baseUrl: {
94+
$schema: {
95+
title: 'Default base URL for SEO properties',
96+
description: [
97+
'It will be used as a default value for sitemap, robots.txt, and Open Graph tags.',
98+
'@example "https://exactpro.github.io"'
99+
].join('\n'),
100+
type: 'string'
101+
}
102+
},
93103
keywords: {
94104
$schema: {
95105
title: 'Keywords for the documentation',

server/routes/robots.txt.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414
* limitations under the License.
1515
*/
1616

17+
import { resolveURL } from 'ufo'
18+
import { useToolkitConfig } from '../../composables/config'
19+
1720
const keysToTemplates = {
1821
UserAgent: (input: string) => `User-agent: ${input}`,
1922
CrawlDelay: (input: string) => `Crawl-delay: ${input}`,
@@ -34,8 +37,8 @@ export type RobotsTxtOptions = {
3437
export default defineEventHandler((event) => {
3538
setHeader(event, 'Content-Type', 'text/plain')
3639
const lines: string[] = []
37-
const config = useAppConfig()
38-
for (const robotOptionsItem of config.exactproDocs?.seo?.robots ?? []) {
40+
const config = useToolkitConfig()
41+
for (const robotOptionsItem of config.seo?.robots ?? []) {
3942
for (const [key, value] of Object.entries(robotOptionsItem)) {
4043
if (typeof value === 'string') {
4144
lines.push(keysToTemplates[key as keyof typeof keysToTemplates](value))
@@ -46,10 +49,10 @@ export default defineEventHandler((event) => {
4649
}
4750
}
4851
}
49-
if (config.exactproDocs?.seo?.sitemap?.baseUrl) {
52+
if (config.seo?.sitemap?.baseUrl) {
5053
lines.push('')
5154
lines.push(
52-
`Sitemap: ${config.exactproDocs.seo.sitemap.baseUrl}/sitemap.xml`
55+
`Sitemap: ${resolveURL(config.seo.sitemap.baseUrl, 'sitemap.xml')}`
5356
)
5457
}
5558
return lines.join('\n')

server/routes/sitemap.xml.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,11 @@
1717
import { SitemapStream, streamToPromise } from 'sitemap'
1818
import { joinURL, parseURL, withProtocol } from 'ufo'
1919
import { withTrailingSlash } from '../../utils/navigation'
20+
import { useToolkitConfig } from '../../composables/config'
2021
import { serverQueryContent } from '#content/server'
21-
const appConfig = useAppConfig()
22+
const config = useToolkitConfig()
2223

23-
const path = parseURL(appConfig.exactproDocs.seo?.sitemap?.baseUrl ?? '')
24+
const path = parseURL(config.seo?.sitemap?.baseUrl ?? '')
2425

2526
export default defineEventHandler(async (event) => {
2627
// Fetch all documents

0 commit comments

Comments
 (0)