-
Notifications
You must be signed in to change notification settings - Fork 27
/
index.tsx
182 lines (166 loc) · 5.33 KB
/
index.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: MPL-2.0
*/
import { useRouter } from 'next/router'
import HashiHead from '@hashicorp/react-head'
import { useCurrentProduct } from 'contexts'
import getDeployedUrl from 'lib/get-deployed-url'
import { HeadMetadataProps } from './types'
/**
* Returns the fully qualified developer URL for the current page, minus the query string
*
* TODO: If we want to support specific query params in the canonical, consider adding an allow list here and instead filtering the search params based on that
*/
const useFullUrl = (base: string = __config.dev_dot.canonical_base_url) => {
const { asPath } = useRouter()
const url = new URL(asPath, base)
// remove any query params from the URL to ensure they don't end up in the canonical
url.search = ''
return url.toString()
}
/**
* Builds up the the necessary meta tags for the site. Rendered in `_app`, where it receives `pageProps.metadata` as props
*
* We build up a page title that looks like {props.title} | {currentProduct} | {root title}
*/
export default function HeadMetadata(props: HeadMetadataProps) {
const { name: productName, slug: productSlug } = useCurrentProduct() ?? {}
// Use the fully qualified current page URL as the canonical URL
const canonicalUrl = useFullUrl()
const titleParts = [__config.dev_dot.meta.title]
const description = props.description ?? __config.dev_dot.meta.description
// We're using .unshift() to add the following elements to the beginning of the array
if (productName) {
titleParts.unshift(productName)
}
if (props.title) {
titleParts.unshift(props.title)
}
const title = titleParts.join(' | ')
const finalDescription = description.replace(
'{product}',
productName ?? 'HashiCorp'
)
const ogImagePath = props.localOgImage || `${productSlug ?? 'base'}.jpg`
const ogImageUrl = `${getDeployedUrl()}/og-image/${ogImagePath}`
/**
* Set a custom favicon based on the environment.
*/
const isDev =
(process.env.HASHI_ENV === 'preview' ||
process.env.HASHI_ENV === 'development') &&
process.env.NODE_ENV === 'development'
const isPreview =
process.env.HASHI_ENV === 'preview' && process.env.NODE_ENV === 'production'
let favIconHref: string
let favIconSvgHref: string
if (isDev) {
favIconHref = '/favicon-dev.ico'
favIconSvgHref = '/favicon-dev.svg'
} else if (isPreview) {
favIconHref = '/favicon-preview.ico'
favIconSvgHref = '/favicon-preview.svg'
} else {
favIconHref = '/favicon.ico'
favIconSvgHref = '/favicon.svg'
}
return (
// TODO: OpenGraph image to be passed as the image prop here
<HashiHead
title={title}
siteName={title}
pageName={title}
description={finalDescription}
image={ogImageUrl}
canonicalUrl={canonicalUrl}
>
{/**
* Note: favicon approach taken from:
* https://dev.to/masakudamatsu/favicon-nightmare-how-to-maintain-sanity-3al7
*
* We've omitted the app icons & web manifest for now, as we're not yet
* trying to support installing the app on a home screen.
*
* If we wanted to simplify our approach here, we could consider using a
* favicon with a background color (say, black hashicorp icon on white
* background), which would remove the need for media queries in the
* SVG icon.
*/}
<link rel="icon" href={favIconHref} sizes="48x48" />
<link rel="icon" href={favIconSvgHref} sizes="any" type="image/svg+xml" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta
name="google-site-verification"
content="zRQZqfAsOX-ypXfU0mzAIzb5rUvj5fA4Zw2jWJRN-JI"
/>
<meta
name="ahrefs-site-verification"
content="9d739b21c466a84dae91df1c79396081a9072152e64f765c9390fed6f249fb84"
/>
{/**
* Note that `key` values here are necessary, as NextJS de-dupes
* `meta` tags based on `name`.
* Ref: https://github.com/vercel/next.js/pull/17099
*
* We have one zd crawler for each product
*/}
<meta
name="zd-site-verification"
key="xnvnvv1i0wl4tf0pzaymb"
content="xnvnvv1i0wl4tf0pzaymb"
data-product="hcp"
/>
<meta
name="zd-site-verification"
key="36fp2i1pj67d8cjtzf4fi9"
content="36fp2i1pj67d8cjtzf4fi9"
data-product="terraform"
/>
<meta
name="zd-site-verification"
key="nbe87kfyp1sck7b13vj1i"
content="nbe87kfyp1sck7b13vj1i"
data-product="packer"
/>
<meta
name="zd-site-verification"
key="wvsmmqa1cfb9am9zlwfj"
content="wvsmmqa1cfb9am9zlwfj"
data-product="consul"
/>
<meta
name="zd-site-verification"
key="cw22oopfwr68ujj0n5pn9i"
content="cw22oopfwr68ujj0n5pn9i"
data-product="boundary"
/>
<meta
name="zd-site-verification"
key="lkslvganwfgfqfwpdeicgh"
content="lkslvganwfgfqfwpdeicgh"
data-product="vault"
/>
<meta
name="zd-site-verification"
key="jl2wp2hoej9rz6c8rmqdns"
content="jl2wp2hoej9rz6c8rmqdns"
data-product="nomad"
/>
<meta
name="zd-site-verification"
key="2eb0cu6xceo73t0038m0tb"
content="2eb0cu6xceo73t0038m0tb"
data-product="waypoint"
/>
<meta
name="zd-site-verification"
key="n52xisxdf3higs2q9kuogd"
content="n52xisxdf3higs2q9kuogd"
data-product="vagrant"
/>
{/* Some og tags do not get picked up for twitter's share cards, so we need these tags as well */}
<meta name="twitter:image" key="twitter:image" content={ogImageUrl} />
</HashiHead>
)
}