47 lines
1.9 KiB
JavaScript
47 lines
1.9 KiB
JavaScript
import { Helmet } from 'react-helmet-async'
|
|
|
|
const DEFAULT_IMAGE = 'https://queuenorth.com/assets/og-image.png'
|
|
const DEFAULT_IMAGE_ALT = 'Queue North Technologies — Business Communications & IT Partner'
|
|
const SITE_NAME = 'Queue North Technologies'
|
|
|
|
const SEO = ({ title, description, url, type = 'website', image = DEFAULT_IMAGE, jsonLd }) => {
|
|
const schemas = jsonLd ? (Array.isArray(jsonLd) ? jsonLd : [jsonLd]) : []
|
|
|
|
return (
|
|
<Helmet>
|
|
<title>{title}</title>
|
|
<meta name="description" content={description} />
|
|
|
|
{/* Canonical URL — prevents duplicate content */}
|
|
<link rel="canonical" href={url} />
|
|
|
|
{/* Open Graph — Facebook, LinkedIn, iMessage, Google Messages, Slack */}
|
|
<meta property="og:title" content={title} />
|
|
<meta property="og:description" content={description} />
|
|
<meta property="og:url" content={url} />
|
|
<meta property="og:type" content={type} />
|
|
<meta property="og:site_name" content={SITE_NAME} />
|
|
<meta property="og:locale" content="en_US" />
|
|
<meta property="og:image" content={image} />
|
|
<meta property="og:image:secure_url" content={image} />
|
|
<meta property="og:image:type" content="image/png" />
|
|
<meta property="og:image:width" content="1200" />
|
|
<meta property="og:image:height" content="630" />
|
|
<meta property="og:image:alt" content={DEFAULT_IMAGE_ALT} />
|
|
|
|
{/* Twitter / X — also used by Apple Messages on iOS 13+ */}
|
|
<meta name="twitter:card" content="summary_large_image" />
|
|
<meta name="twitter:title" content={title} />
|
|
<meta name="twitter:description" content={description} />
|
|
<meta name="twitter:image" content={image} />
|
|
<meta name="twitter:image:alt" content={DEFAULT_IMAGE_ALT} />
|
|
|
|
{schemas.map((schema, i) => (
|
|
<script key={i} type="application/ld+json">{JSON.stringify(schema)}</script>
|
|
))}
|
|
</Helmet>
|
|
)
|
|
}
|
|
|
|
export default SEO
|