From 4df1fb95e0097edaa5d3207480c8bbe60056dd29 Mon Sep 17 00:00:00 2001 From: rayangler <27821750+rayangler@users.noreply.github.com> Date: Wed, 11 Sep 2024 16:11:10 -0400 Subject: [PATCH 1/6] DOP-4920: Add SearchAction structured data (#1230) --- src/components/DocumentBody.js | 2 +- src/components/StructuredData/DocsLandingSD.js | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/components/DocumentBody.js b/src/components/DocumentBody.js index 7d7c78f8c..20b82c43a 100644 --- a/src/components/DocumentBody.js +++ b/src/components/DocumentBody.js @@ -223,7 +223,7 @@ export const Head = ({ pageContext, data }) => { const pageTitle = getPlaintext(getNestedValue(['slugToTitle', lookup], metadata)); const siteTitle = getSiteTitle(metadata); - const isDocsLandingHomepage = metadata.project === 'landing' && template === 'landing'; + const isDocsLandingHomepage = metadata.project === 'landing' && template === 'landing' && slug === '/'; const needsBreadcrumbs = template === 'document' || template === undefined; // Retrieves the canonical URL based on certain situations diff --git a/src/components/StructuredData/DocsLandingSD.js b/src/components/StructuredData/DocsLandingSD.js index f599ffadd..4f83fe332 100644 --- a/src/components/StructuredData/DocsLandingSD.js +++ b/src/components/StructuredData/DocsLandingSD.js @@ -18,6 +18,14 @@ const DocsLandingSD = () => ( }, author: 'MongoDB Documentation Team', inLanguage: 'English', + potentialAction: { + '@type': 'SearchAction', + target: { + '@type': 'EntryPoint', + urlTemplate: 'https://mongodb.com/docs/search/?q={search_term_string}&page=1', + }, + 'query-input': 'required name=search_term_string', + }, })} ); From e85adf0bbec64e5669eb2aa8af2955e7a279e1c8 Mon Sep 17 00:00:00 2001 From: rayangler <27821750+rayangler@users.noreply.github.com> Date: Thu, 19 Sep 2024 11:55:11 -0400 Subject: [PATCH 2/6] DOP-4918: Add VideoObject structured data to Video component (#1236) --- src/components/Video/index.js | 57 ++++++++++++++++----- tests/unit/Video.test.js | 57 ++++++++++++++++++++- tests/unit/__snapshots__/Video.test.js.snap | 4 +- 3 files changed, 100 insertions(+), 18 deletions(-) diff --git a/src/components/Video/index.js b/src/components/Video/index.js index 4b0029e89..922252fb6 100644 --- a/src/components/Video/index.js +++ b/src/components/Video/index.js @@ -68,10 +68,26 @@ const getTheSupportedMedia = (url) => { return REACT_PLAYERS[supportedType]; }; -const Video = ({ nodeData: { argument }, ...rest }) => { +const Video = ({ nodeData: { argument, options = {} } }) => { const url = `${argument[0]['refuri']}`; // use placeholder image for video thumbnail if invalid URL provided const [previewImage, setPreviewImage] = useState(withPrefix('assets/meta_generic.png')); + const { title, description, 'upload-date': uploadDate, 'thumbnail-url': thumbnailUrl } = options; + // Required fields based on https://developers.google.com/search/docs/appearance/structured-data/video#video-object + const hasAllReqFields = [url, title, uploadDate, thumbnailUrl].every((val) => !!val); + + const structuredData = { + '@context': 'https://schema.org', + '@type': 'VideoObject', + embedUrl: url, + name: title, + uploadDate, + thumbnailUrl, + }; + + if (description) { + structuredData['description'] = description; + } useEffect(() => { // handles URL validity checking for well-formed YT links @@ -104,25 +120,38 @@ const Video = ({ nodeData: { argument }, ...rest }) => { } return ( - - } - light={previewImage} - /> - + <> + {hasAllReqFields && ( + + )} + + } + light={previewImage} + /> + + ); }; Video.propTypes = { nodeData: PropTypes.shape({ argument: PropTypes.array.isRequired, + options: PropTypes.shape({ + title: PropTypes.string, + description: PropTypes.string, + 'upload-date': PropTypes.string, + 'thumbnail-url': PropTypes.string, + }), }).isRequired, }; diff --git a/tests/unit/Video.test.js b/tests/unit/Video.test.js index 09adb0924..0c16f2366 100644 --- a/tests/unit/Video.test.js +++ b/tests/unit/Video.test.js @@ -5,12 +5,15 @@ import Video from '../../src/components/Video'; // data for this component import mockData from './data/Video.test.json'; +const REACT_PLAYER_QUERY = 'div.react-player__preview'; +const SD_SCRIPT_QUERY = 'script[type="application/ld+json"]'; + it('YouTube video renders correctly', () => { const tree = render(