Skip to content

Commit

Permalink
feat: replace next-seo with custom solution (vercel#660)
Browse files Browse the repository at this point in the history
* replace next-seo with custom solution

* Updated check

Co-authored-by: LFades <[email protected]>
  • Loading branch information
dominiksipowicz and lfades authored Feb 18, 2022
1 parent 65c9d39 commit db17055
Show file tree
Hide file tree
Showing 8 changed files with 176 additions and 25 deletions.
23 changes: 11 additions & 12 deletions site/components/common/Head/Head.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
import { FC } from 'react'
import NextHead from 'next/head'
import { DefaultSeo } from 'next-seo'
import config from '@config/seo.json'
import type { VFC } from 'react'
import { SEO } from '@components/common'

const Head: FC = () => {
const Head: VFC = () => {
return (
<>
<DefaultSeo {...config} />
<NextHead>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="manifest" href="/site.webmanifest" key="site-manifest" />
</NextHead>
</>
<SEO>
<meta
key="viewport"
name="viewport"
content="width=device-width, initial-scale=1"
/>
<link rel="manifest" href="/site.webmanifest" key="site-manifest" />
</SEO>
)
}

Expand Down
157 changes: 157 additions & 0 deletions site/components/common/SEO/SEO.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
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
1 change: 1 addition & 0 deletions site/components/common/SEO/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './SEO'
1 change: 1 addition & 0 deletions site/components/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ export { default as Searchbar } from './Searchbar'
export { default as UserNav } from './UserNav'
export { default as Head } from './Head'
export { default as I18nWidget } from './I18nWidget'
export { default as SEO } from './SEO'
8 changes: 4 additions & 4 deletions site/components/product/ProductView/ProductView.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import cn from 'clsx'
import Image from 'next/image'
import { NextSeo } from 'next-seo'
import s from './ProductView.module.css'
import { FC } from 'react'
import type { Product } from '@commerce/types/product'
import usePrice from '@framework/product/use-price'
import { WishlistButton } from '@components/wishlist'
import { ProductSlider, ProductCard } from '@components/product'
import { Container, Text } from '@components/ui'
import { SEO } from '@components/common'
import ProductSidebar from '../ProductSidebar'
import ProductTag from '../ProductTag'
interface ProductViewProps {
Expand Down Expand Up @@ -89,7 +89,7 @@ const ProductView: FC<ProductViewProps> = ({ product, relatedProducts }) => {
</div>
</section>
</Container>
<NextSeo
<SEO
title={product.name}
description={product.description}
openGraph={{
Expand All @@ -99,8 +99,8 @@ const ProductView: FC<ProductViewProps> = ({ product, relatedProducts }) => {
images: [
{
url: product.images[0]?.url!,
width: 800,
height: 600,
width: '800',
height: '600',
alt: product.name,
},
],
Expand Down
5 changes: 2 additions & 3 deletions site/config/seo.json → site/config/seo_meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,13 @@
"title": "ACME Storefront | Powered by Next.js Commerce",
"description": "Next.js Commerce - https://www.nextjs.org/commerce",
"type": "website",
"locale": "en_IE",
"url": "https://nextjs.org/commerce",
"site_name": "Next.js Commerce",
"images": [
{
"url": "/card.png",
"width": 800,
"height": 600,
"width": "800",
"height": "600",
"alt": "Next.js Commerce"
}
]
Expand Down
1 change: 0 additions & 1 deletion site/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
"lodash.random": "^3.2.0",
"lodash.throttle": "^4.1.1",
"next": "^12.0.8",
"next-seo": "^4.28.1",
"next-themes": "^0.0.15",
"postcss": "^8.3.5",
"postcss-nesting": "^8.0.1",
Expand Down
5 changes: 0 additions & 5 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4763,11 +4763,6 @@ natural-compare@^1.4.0:
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=

next-seo@^4.28.1:
version "4.29.0"
resolved "https://registry.yarnpkg.com/next-seo/-/next-seo-4.29.0.tgz#d281e95ba47914117cc99e9e468599f0547d9b9b"
integrity sha512-xmwzcz4uHaYJ8glbuhs6FSBQ7z3irmdPYdJJ5saWm72Uy3o+mPKGaPCXQetTCE6/xxVnpoDV4yFtFlEjUcljSg==

next-themes@^0.0.15:
version "0.0.15"
resolved "https://registry.yarnpkg.com/next-themes/-/next-themes-0.0.15.tgz#ab0cee69cd763b77d41211f631e108beab39bf7d"
Expand Down

0 comments on commit db17055

Please sign in to comment.