From db170558d55ee34b4bf86635f78d1aecc9269fa7 Mon Sep 17 00:00:00 2001 From: Dom Sip Date: Fri, 18 Feb 2022 09:26:31 +0000 Subject: [PATCH] feat: replace next-seo with custom solution (#660) * replace next-seo with custom solution * Updated check Co-authored-by: LFades --- site/components/common/Head/Head.tsx | 23 ++- site/components/common/SEO/SEO.tsx | 157 ++++++++++++++++++ site/components/common/SEO/index.ts | 1 + site/components/common/index.ts | 1 + .../product/ProductView/ProductView.tsx | 8 +- site/config/{seo.json => seo_meta.json} | 5 +- site/package.json | 1 - yarn.lock | 5 - 8 files changed, 176 insertions(+), 25 deletions(-) create mode 100644 site/components/common/SEO/SEO.tsx create mode 100644 site/components/common/SEO/index.ts rename site/config/{seo.json => seo_meta.json} (90%) diff --git a/site/components/common/Head/Head.tsx b/site/components/common/Head/Head.tsx index b2c0c997b..ed43c0d39 100644 --- a/site/components/common/Head/Head.tsx +++ b/site/components/common/Head/Head.tsx @@ -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 ( - <> - - - - - - + + + + ) } diff --git a/site/components/common/SEO/SEO.tsx b/site/components/common/SEO/SEO.tsx new file mode 100644 index 000000000..b5e3ad23b --- /dev/null +++ b/site/components/common/SEO/SEO.tsx @@ -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 ( + + + + + + + ) +} + +const SEO: FC = ({ + 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 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 ( + + + {title ? `${config.titleTemplate.replace(/%s/g, title)}` : config.title} + + + + + + + + {openGraph?.locale && ( + + )} + {openGraph?.images?.length + ? openGraph.images.map((img, index) => ogImage(img, index)) + : ogImage(config.openGraph.images[0], 0)} + {config.twitter.cardType && ( + + )} + {config.twitter.site && ( + + )} + {config.twitter.handle && ( + + )} + + + {children} + + ) +} + +export default SEO diff --git a/site/components/common/SEO/index.ts b/site/components/common/SEO/index.ts new file mode 100644 index 000000000..e20ec8600 --- /dev/null +++ b/site/components/common/SEO/index.ts @@ -0,0 +1 @@ +export { default } from './SEO' diff --git a/site/components/common/index.ts b/site/components/common/index.ts index 98dd3394b..054110c75 100644 --- a/site/components/common/index.ts +++ b/site/components/common/index.ts @@ -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' diff --git a/site/components/product/ProductView/ProductView.tsx b/site/components/product/ProductView/ProductView.tsx index b20c85b0a..31cbcd577 100644 --- a/site/components/product/ProductView/ProductView.tsx +++ b/site/components/product/ProductView/ProductView.tsx @@ -1,6 +1,5 @@ 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' @@ -8,6 +7,7 @@ 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 { @@ -89,7 +89,7 @@ const ProductView: FC = ({ product, relatedProducts }) => { - = ({ product, relatedProducts }) => { images: [ { url: product.images[0]?.url!, - width: 800, - height: 600, + width: '800', + height: '600', alt: product.name, }, ], diff --git a/site/config/seo.json b/site/config/seo_meta.json similarity index 90% rename from site/config/seo.json rename to site/config/seo_meta.json index 82520cf9b..c9c5fc226 100644 --- a/site/config/seo.json +++ b/site/config/seo_meta.json @@ -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" } ] diff --git a/site/package.json b/site/package.json index 7a28e7e7b..f5b38acfd 100644 --- a/site/package.json +++ b/site/package.json @@ -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", diff --git a/yarn.lock b/yarn.lock index 1c1a7fc7b..302dd2402 100644 --- a/yarn.lock +++ b/yarn.lock @@ -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"