diff --git a/src/components/SocialSharingMeta/SocialSharingMeta.tsx b/src/components/SocialSharingMeta/SocialSharingMeta.tsx new file mode 100644 index 00000000..f2db309b --- /dev/null +++ b/src/components/SocialSharingMeta/SocialSharingMeta.tsx @@ -0,0 +1,93 @@ +import React, {Fragment} from 'react'; +import {Helmet} from 'react-helmet'; + +export type MetaProps = JSX.IntrinsicElements['meta']; + +export interface SocialSharingMetaProps { + url?: string; + title?: string; + description?: string; + image?: string; + imageWidth?: number; + imageHeight?: number; + type?: string; + locale?: string; + extra?: MetaProps[]; + withoutHelmet?: boolean; + children?: React.ReactNode; +} + +export const SocialSharingMeta: React.FC = (props) => { + const renderSchemaOrgTag = (name: string, value?: string | number) => { + return value && ; + }; + + const renderOpenGraphTag = (name: string, value?: string | number) => { + return ( + value && ( + + ) + ); + }; + + const renderTwitterTag = (name: string, value?: string | number) => { + return ( + value && ( + + ) + ); + }; + + const renderExtraMeta = (props: MetaProps, index: number) => { + return React.createElement('meta', {...props, key: `extra-${index}`}); + }; + + const { + url, + title, + description, + image, + imageWidth, + imageHeight, + type, + locale, + extra, + children, + withoutHelmet, + } = props; + let meta = [ + renderSchemaOrgTag('name', title), + renderSchemaOrgTag('description', description), + renderSchemaOrgTag('image', image), + + renderOpenGraphTag('type', type), + renderOpenGraphTag('url', url), + renderOpenGraphTag('title', title), + renderOpenGraphTag('description', description), + renderOpenGraphTag('image', image), + renderOpenGraphTag('image:width', imageWidth), + renderOpenGraphTag('image:height', imageHeight), + renderOpenGraphTag('locale', locale), + + title && renderTwitterTag('card', 'summary_large_image'), + renderTwitterTag('title', title), + renderTwitterTag('description', description), + renderTwitterTag('image', image), + ].filter(Boolean); + + if (extra) { + meta = meta.concat(extra.map(renderExtraMeta)); + } + + return withoutHelmet ? ( + + {meta} + {children} + + ) : ( + + {meta} + {children} + + ); +}; diff --git a/src/components/SocialSharingMeta/index.ts b/src/components/SocialSharingMeta/index.ts new file mode 100644 index 00000000..adc57251 --- /dev/null +++ b/src/components/SocialSharingMeta/index.ts @@ -0,0 +1 @@ +export * from './SocialSharingMeta';