1
0
mirror of https://github.com/vercel/commerce.git synced 2025-08-11 19:31:23 +00:00
Files
.github
.vscode
ISSUE_TEMPLATE
cypress
packages
site
assets
components
auth
cart
checkout
common
Avatar
FeatureBar
Footer
Head
HomeAllProductsGrid
I18nWidget
Layout
Navbar
SEO
SEO.tsx
index.ts
Searchbar
SidebarLayout
UserNav
index.ts
icons
product
ui
wishlist
search.tsx
config
lib
pages
public
.env.template
.eslintrc
.gitignore
.prettierignore
.prettierrc
comments.md
commerce-config.js
commerce.config.json
global.d.ts
next-env.d.ts
next.config.js
package.json
postcss.config.js
tailwind.config.js
tsconfig.json
.editorconfig
.gitignore
.prettierignore
.prettierrc
README.md
cypress.json
license.md
package.json
turbo.json
yarn.lock
commerce/site/components/common/SEO/SEO.tsx
Dom Sip db170558d5 feat: replace next-seo with custom solution ()
* replace next-seo with custom solution

* Updated check

Co-authored-by: LFades <luis@vercel.com>
2022-02-18 04:26:31 -05:00

158 lines
3.9 KiB
TypeScript

import Head from 'next/head'
import { FC, Fragment, ReactNode } from 'react'
import config from '@config/seo_meta.json'
const storeUrl =
process.env.NEXT_PUBLIC_STORE_URL || process.env.NEXT_PUBLIC_VERCEL_URL
const storeBaseUrl = storeUrl ? `https://${storeUrl}` : null
interface OgImage {
url?: string
width?: string
height?: string
alt?: string
}
interface Props {
title?: string
description?: string
robots?: string
openGraph?: {
title?: string
type?: string
locale?: string
description?: string
site_name?: string
url?: string
images?: OgImage[]
}
children?: ReactNode
}
const ogImage = ({ url, width, height, alt }: OgImage, index: number) => {
// generate full URL for OG image url with store base URL
const imgUrl = storeBaseUrl ? new URL(url!, storeBaseUrl).toString() : url
return (
<Fragment key={`og:image:${index}`}>
<meta
key={`og:image:url:${index}`}
property="og:image"
content={imgUrl}
/>
<meta
key={`og:image:width:${index}`}
property="og:image:width"
content={width}
/>
<meta
key={`og:image:height:${index}`}
property="og:image:height"
content={height}
/>
<meta
key={`og:image:alt:${index}`}
property="og:image:alt"
content={alt}
/>
</Fragment>
)
}
const SEO: FC<Props> = ({
title,
description,
openGraph,
robots,
children,
}) => {
/**
* @see https://nextjs.org/docs/api-reference/next/head
*
* meta or any other elements need to be contained as direct children of the Head element,
* or wrapped into maximum one level of <React.Fragment> or arrays
* otherwise the tags won't be correctly picked up on client-side navigations.
*
* The `key` property makes the tag is only rendered once,
*/
return (
<Head>
<title key="title">
{title ? `${config.titleTemplate.replace(/%s/g, title)}` : config.title}
</title>
<meta
key="description"
name="description"
content={description || config.description}
/>
<meta
key="og:type"
property="og:type"
content={openGraph?.type ?? config.openGraph.type}
/>
<meta
key="og:title"
property="og:title"
content={
openGraph?.title ?? config.openGraph.title ?? title ?? config.title
}
/>
<meta
key="og:description"
property="og:description"
content={
openGraph?.description ??
config.openGraph.description ??
description ??
config.description
}
/>
<meta
key="og:site_name"
property="og:site_name"
content={openGraph?.site_name ?? config.openGraph.site_name}
/>
<meta
key="og:url"
property="og:url"
content={openGraph?.url ?? config.openGraph.url}
></meta>
{openGraph?.locale && (
<meta key="og:locale" property="og:locale" content={openGraph.locale} />
)}
{openGraph?.images?.length
? openGraph.images.map((img, index) => ogImage(img, index))
: ogImage(config.openGraph.images[0], 0)}
{config.twitter.cardType && (
<meta
key="twitter:card"
name="twitter:card"
content={config.twitter.cardType}
/>
)}
{config.twitter.site && (
<meta
key="twitter:site"
name="twitter:site"
content={config.twitter.site}
/>
)}
{config.twitter.handle && (
<meta
key="twitter:creator"
name="twitter:creator"
content={config.twitter.handle}
/>
)}
<meta key="robots" name="robots" content={robots ?? 'index,follow'} />
<meta
key="googlebot"
name="googlebot"
content={robots ?? 'index,follow'}
></meta>
{children}
</Head>
)
}
export default SEO