Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 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 | 1x 1x 1x 1x 1x 1x 2x 2x 2x 2x 2x 2x 2x 2x | import { useRouter } from 'next/router';
import React from 'react';
import { author as auth } from '@/constants/site';
import { getLang, cleanTrailingSlash } from '@/helpers';
import Head from 'next/head';
 
type Props = {
    isBlog?: boolean;
    noimage?: boolean;
    meta?: {
        noindex?: boolean;
        title: string;
        author?: string;
        description?: string;
        image?: string;
        category?: string;
        alternate?: Array<{ lang: string; url: string }>;
        slug?: string;
        url?: string;
    };
};
 
/**
 * @example
 *     <SEO meta={meta} isBlog={true} />;
 *
 * @param {object} meta - The object containing the meta data for SEO
 * @param {boolean} isBlog - Whether the page is a blog post the SEO changes
 * @param {boolean} noimage - Whether to show the image in the SEO
 * @returns {JSX.Element}
 */
const SEO = ({ meta, isBlog, noimage = true }: Props) => {
    const { locale: l, pathname: path } = useRouter();
    const category = meta?.category?.toLowerCase();
    const url = isBlog
        ? `${process.env.NEXT_PUBLIC_DOMAIN}${getLang(l)}/blog/${category}/${meta?.slug}`
        : `${process.env.NEXT_PUBLIC_DOMAIN}${getLang(l)}${cleanTrailingSlash(path)}`;
    const title = meta?.title;
    const author = meta?.author || auth;
    const description = meta?.description;
    const image = meta?.image ?? '/profile.png';
 
    return (
        <>
            <Head>
                {isBlog ? (
                    <script
                        data-testid="json-ld"
                        type="application/ld+json"
                        key="item-jsonld"
                        dangerouslySetInnerHTML={{
                            __html: JSON.stringify({
                                '@context': 'https://schema.org',
                                '@type': 'Article',
                                headline: title,
                                description: description,
                                url: url,
                                ...(image && { image: [`${process.env.NEXT_PUBLIC_DOMAIN}/${image}`] }),
                                datePublished: new Date().toISOString(),
                                dateModified: new Date().toISOString(),
                                author: [
                                    {
                                        '@type': 'Person',
                                        name: author,
                                        url: process.env.NEXT_PUBLIC_DOMAIN,
                                    },
                                ],
                            }),
                        }}
                    />
                ) : (
                    <>
                        <link
                            hrefLang="es"
                            rel="alternate"
                            href={`${process.env.NEXT_PUBLIC_DOMAIN}/es${cleanTrailingSlash(path)}`}
                        />
                        <link
                            hrefLang="gl"
                            rel="alternate"
                            href={`${process.env.NEXT_PUBLIC_DOMAIN}/gl${cleanTrailingSlash(path)}`}
                        />
                    </>
                )}
 
                <title>{title}</title>
                {meta?.noindex ? (
                    <>
                        <meta name="robots" content="noindex" />
                        <meta name="googlebot" content="noindex" />
                    </>
                ) : (
                    <>
                        <meta name="robots" content="index,follow" />
                        <meta name="googlebot" content="index,follow" />
                    </>
                )}
                <meta name="author" content={author} />
                <meta name="description" content={description} />
                <meta property="og:description" content={description} />
                <meta name="twitter:description" content={description} />
                <meta property="og:title" content={title} />
                <meta name="twitter:title" content={title} />
                {noimage && (
                    <>
                        <meta name="image" content={image} />
                        <meta property="og:image" content={`${process.env.NEXT_PUBLIC_DOMAIN}${image}`} />
                    </>
                )}
                <meta property="og:url" content={url} />
                <link rel="canonical" href={url} title="Canonical url" />
                {meta?.alternate?.map(({ lang, url }, index) => (
                    <link
                        data-testid="blog-alternate"
                        key={index}
                        rel="alternate"
                        href={`${process.env.NEXT_PUBLIC_DOMAIN}${getLang(lang)}/blog/${category}/${url}`}
                        hrefLang={lang}
                        title={`Alternate url for langueage ${lang}`}
                    />
                ))}
            </Head>
        </>
    );
};
 
export default SEO;
  |