From 3ca87c9553f7e19ac9ccc16972112e642735c119 Mon Sep 17 00:00:00 2001 From: Wiebke Freitag Date: Wed, 29 Nov 2023 14:35:45 +0100 Subject: [PATCH 1/7] feat: replace react-helmet with gatsby head api --- gatsby-config.ts | 1 - package.json | 3 -- src/components/layout/seo.tsx | 12 ++--- .../career-details-structured-data.tsx | 7 +-- .../pages/contact/leaflet/leaflet.tsx | 19 +------ .../structured-organization-data.tsx | 7 +-- src/pages/404.tsx | 30 ++++++----- src/pages/about-us.tsx | 38 +++++++------ src/pages/career.tsx | 53 ++++++++++--------- src/pages/contact.tsx | 21 ++++++-- src/pages/data-privacy.tsx | 21 +++++--- src/pages/imprint.tsx | 19 ++++--- src/pages/index.tsx | 35 ++++++------ src/pages/services.tsx | 44 +++++++-------- src/templates/blog-post-overview.tsx | 37 +++++++------ src/templates/blog-post.tsx | 31 +++++++---- src/templates/career-details.tsx | 21 +++++--- yarn.lock | 36 +------------ 18 files changed, 212 insertions(+), 223 deletions(-) diff --git a/gatsby-config.ts b/gatsby-config.ts index f56069881..b2cfe76c8 100644 --- a/gatsby-config.ts +++ b/gatsby-config.ts @@ -44,7 +44,6 @@ const gatsbyConfig: GatsbyConfig = { }, plugins: [ `gatsby-plugin-sass`, - 'gatsby-plugin-react-helmet', `gatsby-plugin-smoothscroll`, `gatsby-plugin-image`, `gatsby-plugin-catch-links` /* Please use gatsby-link for remark content */, diff --git a/package.json b/package.json index 72eef6e72..be4700d20 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,6 @@ "gatsby-plugin-gatsby-cloud": "^5.12.2", "gatsby-plugin-image": "^3.12.3", "gatsby-plugin-manifest": "^5.12.3", - "gatsby-plugin-react-helmet": "^6.10.0", "gatsby-plugin-react-i18next": "^3.0.1", "gatsby-plugin-readingtime": "^3.0.1", "gatsby-plugin-robots-txt": "^1.8.0", @@ -78,7 +77,6 @@ "react": "^18.2.0", "react-dom": "^18.2.0", "react-dropzone": "^14.2.3", - "react-helmet": "^6.1.0", "react-hook-form": "^7.44.2", "react-i18next": "^13.5.0", "react-leaflet": "^4.2.1", @@ -108,7 +106,6 @@ "@types/node": "^20.10.0", "@types/react": "^18.2.39", "@types/react-dom": "^18.2.17", - "@types/react-helmet": "^6.1.9", "@types/react-syntax-highlighter": "^15.5.10", "@types/showdown": "^2.0.6", "@types/styled-components": "^5.1.32", diff --git a/src/components/layout/seo.tsx b/src/components/layout/seo.tsx index 461772a16..197a8d749 100644 --- a/src/components/layout/seo.tsx +++ b/src/components/layout/seo.tsx @@ -1,6 +1,5 @@ import { graphql, useStaticQuery } from 'gatsby'; import React from 'react'; -import { Helmet } from 'react-helmet'; import { useI18next } from 'gatsby-plugin-react-i18next'; import { useTranslation } from 'gatsby-plugin-react-i18next'; import { I18nNextData } from '../../types'; @@ -92,12 +91,9 @@ const SEO = ({ ); return ( - + <> + + {title} {/* Standard Tags */} )} - + ); }; diff --git a/src/components/pages/career-details/career-details-structured-data.tsx b/src/components/pages/career-details/career-details-structured-data.tsx index 80cf0aab6..354977304 100644 --- a/src/components/pages/career-details/career-details-structured-data.tsx +++ b/src/components/pages/career-details/career-details-structured-data.tsx @@ -1,5 +1,4 @@ import React from 'react'; -import { Helmet } from 'react-helmet'; import { ContentfulVacancy } from '../../../types'; import { JobPosting, WithContext } from 'schema-dts'; import { renderRichText } from 'gatsby-source-contentful/rich-text'; @@ -78,10 +77,6 @@ export const CareerDetailsStructuredData = ({ }; return ( - - - + ); }; diff --git a/src/components/pages/contact/leaflet/leaflet.tsx b/src/components/pages/contact/leaflet/leaflet.tsx index 17dfe26bb..e73ffa7f9 100644 --- a/src/components/pages/contact/leaflet/leaflet.tsx +++ b/src/components/pages/contact/leaflet/leaflet.tsx @@ -2,7 +2,6 @@ import * as L from 'leaflet'; import { LatLngExpression } from 'leaflet'; import { GestureHandling } from 'leaflet-gesture-handling'; import React, { useEffect, useState } from 'react'; -import { Helmet } from 'react-helmet'; import { useTranslation } from 'gatsby-plugin-react-i18next'; import { CircleMarker, @@ -140,21 +139,5 @@ export const Leaflet = () => { ); - return ( - - - - - - - {MapView} - - ); + return {MapView}; }; diff --git a/src/components/pages/landingpage/structured-organization-data.tsx b/src/components/pages/landingpage/structured-organization-data.tsx index 86f9997d2..cb228726d 100644 --- a/src/components/pages/landingpage/structured-organization-data.tsx +++ b/src/components/pages/landingpage/structured-organization-data.tsx @@ -1,5 +1,4 @@ import React from 'react'; -import { Helmet } from 'react-helmet'; /** * This adds Structured Data for the Satellytes Organization based on https://schema.org/Organization @@ -30,9 +29,5 @@ export const StructuredOrganizationData = () => { ], }; - return ( - - - - ); + return ; }; diff --git a/src/pages/404.tsx b/src/pages/404.tsx index 822ad458d..a3559cc17 100644 --- a/src/pages/404.tsx +++ b/src/pages/404.tsx @@ -12,27 +12,29 @@ interface NotFoundPageQueryProps { const NotFoundPage = ({ data, - location, }: PageProps): JSX.Element => { return ( - <> - - - - - {data.contentfulPage.description?.description as string} - - - - + + + + {data.contentfulPage.description?.description as string} + + + ); }; export default NotFoundPage; +export const Head = ({ data, location }: PageProps) => { + return ( + + ); +}; + export const NotFoundPageQuery = graphql` query ($language: String!) { contentfulPage(slug: { eq: "not-found" }, node_locale: { eq: $language }) { diff --git a/src/pages/about-us.tsx b/src/pages/about-us.tsx index e0c5f4d69..38c2d8bf3 100644 --- a/src/pages/about-us.tsx +++ b/src/pages/about-us.tsx @@ -25,28 +25,32 @@ interface AboutUsQueryProps { }; } -const AboutUs = ({ data, location }: PageProps) => { +const AboutUs = ({ data }: PageProps) => { return ( - <> - - - + ); }; export default AboutUs; + +export const Head = ({ data, location }: PageProps) => { + return ( + + ); +}; + export const AboutUsPageQuery = graphql` query ($language: String!) { hero: file(relativePath: { eq: "office/sy-office-05.jpg" }) { diff --git a/src/pages/career.tsx b/src/pages/career.tsx index b47665270..e445f7da4 100644 --- a/src/pages/career.tsx +++ b/src/pages/career.tsx @@ -33,42 +33,45 @@ interface CareerPageQueryProps { applicationProcessAccordion: ContentfulAccordion; } -const Career = ({ data, location }: PageProps) => { +const Career = ({ data }: PageProps) => { const officeImages = data.officeImages.nodes.reduce((memo, image) => { memo[image.relativePath] = image; return memo; }, {}); return ( - <> - - - + ); }; export default Career; +export const Head = ({ data, location }: PageProps) => { + return ( + + ); +}; + export const CareerPageQuery = graphql` query ($language: String!) { officeImages: allFile(filter: { relativeDirectory: { eq: "office" } }) { diff --git a/src/pages/contact.tsx b/src/pages/contact.tsx index e40168296..af9003a2c 100644 --- a/src/pages/contact.tsx +++ b/src/pages/contact.tsx @@ -8,7 +8,10 @@ interface ContactPageQueryProps { contentfulPage: ContentfulPage; } -const Contact = ({ data, location }: PageProps) => { +const Contact = () => ; +export default Contact; + +export const Head = ({ data, location }: PageProps) => { return ( <> ) => { description={data.contentfulPage.description?.description} location={location} /> - + {/* + * Styles and Script for Leaflet Hero Map + */} + + + ); }; -export default Contact; - export const ContactPageQuery = graphql` query ($language: String!) { contentfulPage(slug: { eq: "contact" }, node_locale: { eq: $language }) { diff --git a/src/pages/data-privacy.tsx b/src/pages/data-privacy.tsx index c913bdd42..04142d907 100644 --- a/src/pages/data-privacy.tsx +++ b/src/pages/data-privacy.tsx @@ -12,16 +12,9 @@ interface DataPrivacyPageQueryProps { const DataPrivacyPage = ({ data, - location, }: PageProps): JSX.Element => { return ( - ) => { + return ( + + ); +}; + export default DataPrivacyPage; export const DataPrivacyPageQuery = graphql` diff --git a/src/pages/imprint.tsx b/src/pages/imprint.tsx index a0846f2f3..c0dd69224 100644 --- a/src/pages/imprint.tsx +++ b/src/pages/imprint.tsx @@ -10,15 +10,9 @@ interface ImprintPageQueryProps { contentfulPage: ContentfulPage; } -const ImprintPage = ({ data, location }: PageProps) => { +const ImprintPage = ({ data }: PageProps) => { return ( - ) => { ); }; +export const Head = ({ data, location }: PageProps) => { + return ( + + ); +}; + export default ImprintPage; export const ImprintPageQuery = graphql` diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 98fb72b8f..9e97fb056 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -36,7 +36,7 @@ interface IndexPageQueryProps { blogHeader: ContentfulSectionHeader; } -const IndexPage = ({ data, location }: PageProps) => { +const IndexPage = ({ data }: PageProps) => { const jobPositions = data.allContentfulVacancy.nodes; const blogPosts = data.allContentfulBlogPost.nodes; const officeImages = data.officeImages.nodes.reduce((memo, image) => { @@ -44,29 +44,32 @@ const IndexPage = ({ data, location }: PageProps) => { return memo; }, {}); + return ( + + ); +}; + +export default IndexPage; + +export const Head = ({ data, location }: PageProps) => { return ( <> - - - ); }; -export default IndexPage; - export const IndexPageQuery = graphql` query ($language: String!) { officeImages: allFile(filter: { relativeDirectory: { eq: "office" } }) { diff --git a/src/pages/services.tsx b/src/pages/services.tsx index b0b5c066e..a17d85def 100644 --- a/src/pages/services.tsx +++ b/src/pages/services.tsx @@ -22,34 +22,34 @@ interface ServicesPageQueryProps { consultingList: ContentfulList; } -const ServicesPage = ({ - data, - location, -}: PageProps) => { +const ServicesPage = ({ data }: PageProps) => { return ( - <> - - - + ); }; export default ServicesPage; +export const Head = ({ data, location }: PageProps) => { + return ( + + ); +}; + export const ServicesPageQuery = graphql` query ($language: String!) { contentfulPage(slug: { eq: "services" }, node_locale: { eq: $language }) { diff --git a/src/templates/blog-post-overview.tsx b/src/templates/blog-post-overview.tsx index 19fb042d8..c74a93940 100644 --- a/src/templates/blog-post-overview.tsx +++ b/src/templates/blog-post-overview.tsx @@ -28,32 +28,37 @@ interface BlogPageQueryProps { const Blog = ({ data, - location, pageContext, }: PageProps) => { const blogPosts = data.allContentfulBlogPost.nodes; return ( - <> - - - + ); }; export default Blog; +export const Head = ({ + pageContext, + location, +}: PageProps) => { + return ( + + ); +}; + export const BlogPageQuery = graphql` query ($language: String!, $skip: Int!, $limit: Int!) { allContentfulBlogPost( diff --git a/src/templates/blog-post.tsx b/src/templates/blog-post.tsx index f7003c9df..8027425b5 100644 --- a/src/templates/blog-post.tsx +++ b/src/templates/blog-post.tsx @@ -19,18 +19,35 @@ const BlogArticleTemplate = ({ data, location, }: PageProps): JSX.Element => { - const { author, seoMetaText, title, publicationDate, heroImage } = - data.contentfulBlogPost; + const { title } = data.contentfulBlogPost; const { t } = useTranslation(); - const shareImagePath = heroImage.shareImage.resize.src; - const breadcrumb: BreadcrumbEntry[] = [ { pathname: '/', label: 'Satellytes' }, { pathname: '/blog', label: t('navigation.blog') }, { pathname: location.pathname, label: title }, ]; + return ( + <> + + + ); +}; + +export const Head = ({ + data, + location, +}: PageProps) => { + const { author, seoMetaText, title, publicationDate, heroImage } = + data.contentfulBlogPost; + + const shareImagePath = heroImage.shareImage.resize.src; + return ( <> {/* @@ -50,12 +67,6 @@ const BlogArticleTemplate = ({ location={location} rssLink /> - - ); }; diff --git a/src/templates/career-details.tsx b/src/templates/career-details.tsx index 22c8f671f..dd900448e 100644 --- a/src/templates/career-details.tsx +++ b/src/templates/career-details.tsx @@ -24,6 +24,18 @@ interface CareerPageProps { const CareerPage = (props: CareerPageProps): JSX.Element => { const { pageContext } = props; const position = props.data.contentfulVacancy; + + return ( + + ); +}; + +export const Head = (props: CareerPageProps) => { + const position = props.data.contentfulVacancy; const socialCardPath = position.socialCardFile.childImageSharp.gatsbyImageData.images.fallback ?.src; @@ -39,16 +51,9 @@ const CareerPage = (props: CareerPageProps): JSX.Element => { description={t('career.seo.description-detail', { name: position.name, })} - location={props.location} + location={location} /> - - - ); }; diff --git a/yarn.lock b/yarn.lock index 77168bfac..ad7de427e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3179,13 +3179,6 @@ dependencies: "@types/react" "*" -"@types/react-helmet@^6.1.9": - version "6.1.9" - resolved "https://registry.yarnpkg.com/@types/react-helmet/-/react-helmet-6.1.9.tgz#e79e0def2ad4047cb67e83c5be7cfb3d2121615a" - integrity sha512-nuOeTefP4yPTWHvjGksCBKb/4hsgJxSX7aSTjTIDFXJIkZ6Wo2Y4/cmE1FO9OlYBrHjKOer/0zLwY7s4qiQBtw== - dependencies: - "@types/react" "*" - "@types/react-syntax-highlighter@^15.5.10": version "15.5.10" resolved "https://registry.yarnpkg.com/@types/react-syntax-highlighter/-/react-syntax-highlighter-15.5.10.tgz#697dd4c640baefbfce655d3cd2b54629922ec05f" @@ -7553,13 +7546,6 @@ gatsby-plugin-page-creator@^5.12.3: globby "^11.1.0" lodash "^4.17.21" -gatsby-plugin-react-helmet@^6.10.0: - version "6.12.0" - resolved "https://registry.yarnpkg.com/gatsby-plugin-react-helmet/-/gatsby-plugin-react-helmet-6.12.0.tgz#8e6a2ec967a33a0c48266316c92844ea3272d4b2" - integrity sha512-agcBCT9H8nlpkAU3D1fUeJbjh7IMPjGO/njoa7avIYLGsQ2nyGlHwcrEmS2zBHxYKaxPkztvr47OpCdnuEIvEw== - dependencies: - "@babel/runtime" "^7.20.13" - gatsby-plugin-react-i18next@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/gatsby-plugin-react-i18next/-/gatsby-plugin-react-i18next-3.0.1.tgz#efa264e3cd7bc33d2276ae5ec88ba8d1c59e0714" @@ -12209,7 +12195,7 @@ prompts@^2.0.1, prompts@^2.4.2: kleur "^3.0.3" sisteransi "^1.0.5" -prop-types@^15.7.2, prop-types@^15.8.1: +prop-types@^15.8.1: version "15.8.1" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== @@ -12460,21 +12446,6 @@ react-error-overlay@^6.0.11: resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.11.tgz#92835de5841c5cf08ba00ddd2d677b6d17ff9adb" integrity sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg== -react-fast-compare@^3.1.1: - version "3.2.2" - resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.2.tgz#929a97a532304ce9fee4bcae44234f1ce2c21d49" - integrity sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ== - -react-helmet@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/react-helmet/-/react-helmet-6.1.0.tgz#a750d5165cb13cf213e44747502652e794468726" - integrity sha512-4uMzEY9nlDlgxr61NL3XbKRy1hEkXmKNXhjbAIOVw5vcFrsdYbH2FEwcNyWvWinl103nXgzYNlns9ca+8kFiWw== - dependencies: - object-assign "^4.1.1" - prop-types "^15.7.2" - react-fast-compare "^3.1.1" - react-side-effect "^2.1.0" - react-hook-form@^7.44.2: version "7.48.2" resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.48.2.tgz#01150354d2be61412ff56a030b62a119283b9935" @@ -12537,11 +12508,6 @@ react-share@^5.0.2: classnames "^2.3.2" jsonp "^0.2.1" -react-side-effect@^2.1.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/react-side-effect/-/react-side-effect-2.1.2.tgz#dc6345b9e8f9906dc2eeb68700b615e0b4fe752a" - integrity sha512-PVjOcvVOyIILrYoyGEpDN3vmYNLdy1CajSFNt4TDsVQC5KpTijDvWVoR+/7Rz2xT978D8/ZtFceXxzsPwZEDvw== - react-spring@^9.7.3: version "9.7.3" resolved "https://registry.yarnpkg.com/react-spring/-/react-spring-9.7.3.tgz#3211dea4c4d7c5b541260af5100261b87becb5d5" From a0c04b2760de44cb78b433feb32f29ca1790100a Mon Sep 17 00:00:00 2001 From: Wiebke Freitag Date: Mon, 4 Dec 2023 08:57:45 +0100 Subject: [PATCH 2/7] fix: correct career details page --- src/templates/career-details.tsx | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/templates/career-details.tsx b/src/templates/career-details.tsx index dd900448e..e04ca033a 100644 --- a/src/templates/career-details.tsx +++ b/src/templates/career-details.tsx @@ -6,7 +6,7 @@ import { CareerDetails } from '../components/pages/career-details/career-details import { ContentfulVacancy } from '../types'; import { CareerDetailsStructuredData } from '../components/pages/career-details/career-details-structured-data'; -interface CareerPageProps { +interface CareerDetailsPageQueryProps { pageContext: { language: string; translation: string; @@ -21,9 +21,11 @@ interface CareerPageProps { }; } -const CareerPage = (props: CareerPageProps): JSX.Element => { - const { pageContext } = props; - const position = props.data.contentfulVacancy; +const CareerPage = ({ + pageContext, + data, +}: CareerDetailsPageQueryProps): JSX.Element => { + const position = data.contentfulVacancy; return ( { ); }; -export const Head = (props: CareerPageProps) => { - const position = props.data.contentfulVacancy; +export const Head = ({ location, data }: CareerDetailsPageQueryProps) => { + const position = data.contentfulVacancy; const socialCardPath = position.socialCardFile.childImageSharp.gatsbyImageData.images.fallback ?.src; From 7aa8af54474301e068117921b03c3414f5b431c9 Mon Sep 17 00:00:00 2001 From: Wiebke Freitag Date: Tue, 5 Dec 2023 16:58:16 +0100 Subject: [PATCH 3/7] fix: correct translation in page-head --- src/components/layout/seo.tsx | 32 ++++++++++++++++++++++++---- src/pages/404.tsx | 4 +++- src/pages/about-us.tsx | 4 +++- src/pages/career.tsx | 4 +++- src/pages/contact.tsx | 4 +++- src/pages/data-privacy.tsx | 4 +++- src/pages/imprint.tsx | 4 +++- src/pages/index.tsx | 10 +++++++-- src/pages/services.tsx | 4 +++- src/templates/blog-post-overview.tsx | 5 ++++- src/templates/blog-post.tsx | 4 +++- src/templates/career-details.tsx | 23 ++++++++++++-------- 12 files changed, 78 insertions(+), 24 deletions(-) diff --git a/src/components/layout/seo.tsx b/src/components/layout/seo.tsx index 197a8d749..b494c9cae 100644 --- a/src/components/layout/seo.tsx +++ b/src/components/layout/seo.tsx @@ -1,8 +1,11 @@ import { graphql, useStaticQuery } from 'gatsby'; import React from 'react'; import { useI18next } from 'gatsby-plugin-react-i18next'; -import { useTranslation } from 'gatsby-plugin-react-i18next'; import { I18nNextData } from '../../types'; +import { + DEFAULT_LANGUAGE, + LANGUAGES, +} from '../../../gatsby/config-options/constants'; const DEFAULT_META_IMAGE_URL_PATH = '/sy-share-image.jpg'; const RSS_URL = 'https://satellytes.com/blog/rss.xml'; @@ -18,6 +21,17 @@ interface SeoProps { noIndex?: boolean; location: Location; rssLink?: boolean; + locales: LocalesQueryProps; +} + +export interface LocalesQueryProps { + edges: { + node: { + language: string; + ns: string; + data: string; + }; + }[]; } /** @@ -65,6 +79,7 @@ const SEO = ({ noIndex, location, rssLink, + locales, }: SeoProps) => { const { site } = useStaticQuery(graphql` query { @@ -77,16 +92,25 @@ const SEO = ({ } } `); - const { t } = useTranslation(); const i18n = useI18next(); - const metaDescription = description || t('main.description'); + // Get translation + const dataNode = locales.edges.find((e) => e.node.ns === 'translations') + ?.node; + const t = JSON.parse(dataNode?.data || '{}'); + const metaDescription = description || t['main.description']; const typeOfSite = siteType || 'website'; const metaImageUrl = site.siteMetadata.siteUrl + (shareImagePath ?? DEFAULT_META_IMAGE_URL_PATH); const alternateLanguagesMetaTags = buildAlternateMetaTags( - i18n, + { + languages: LANGUAGES, + language: (dataNode?.language as string) || DEFAULT_LANGUAGE, + originalPath: location.pathname.replace('/de/', '/'), + defaultLanguage: DEFAULT_LANGUAGE, + path: location.pathname, + }, location.origin, ); diff --git a/src/pages/404.tsx b/src/pages/404.tsx index a3559cc17..9840f13cb 100644 --- a/src/pages/404.tsx +++ b/src/pages/404.tsx @@ -3,11 +3,12 @@ import { graphql, PageProps } from 'gatsby'; import { SectionHeader } from '../components/content/section-header/section-header'; import { ContentBlockContainer } from '../components/layout/content-block-container'; import { Layout } from '../components/layout/layout'; -import SEO from '../components/layout/seo'; +import SEO, { LocalesQueryProps } from '../components/layout/seo'; import { ContentfulPage } from '../types'; interface NotFoundPageQueryProps { contentfulPage: ContentfulPage; + locales: LocalesQueryProps; } const NotFoundPage = ({ @@ -31,6 +32,7 @@ export const Head = ({ data, location }: PageProps) => { ); }; diff --git a/src/pages/about-us.tsx b/src/pages/about-us.tsx index 38c2d8bf3..35fe47585 100644 --- a/src/pages/about-us.tsx +++ b/src/pages/about-us.tsx @@ -1,6 +1,6 @@ import { graphql, PageProps } from 'gatsby'; import React from 'react'; -import SEO from '../components/layout/seo'; +import SEO, { LocalesQueryProps } from '../components/layout/seo'; import { AboutUsPage } from '../components/pages/about-us/about-us-page'; import { ContentfulAboutUsImpression, @@ -23,6 +23,7 @@ interface AboutUsQueryProps { allContentfulAboutUsImpressions: { nodes: ContentfulAboutUsImpression[]; }; + locales: LocalesQueryProps; } const AboutUs = ({ data }: PageProps) => { @@ -47,6 +48,7 @@ export const Head = ({ data, location }: PageProps) => { ); }; diff --git a/src/pages/career.tsx b/src/pages/career.tsx index e445f7da4..06747850d 100644 --- a/src/pages/career.tsx +++ b/src/pages/career.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import SEO from '../components/layout/seo'; +import SEO, { LocalesQueryProps } from '../components/layout/seo'; import { graphql, PageProps } from 'gatsby'; import { CareerPage } from '../components/pages/career/career-page'; import { @@ -31,6 +31,7 @@ interface CareerPageQueryProps { cultureTeaser: ContentfulTeaser; perksTeaser: ContentfulTeaser; applicationProcessAccordion: ContentfulAccordion; + locales: LocalesQueryProps; } const Career = ({ data }: PageProps) => { @@ -68,6 +69,7 @@ export const Head = ({ data, location }: PageProps) => { title={`${data.contentfulPage.title} | Satellytes`} description={data.contentfulPage.seoMetaText} location={location} + locales={data.locales} /> ); }; diff --git a/src/pages/contact.tsx b/src/pages/contact.tsx index af9003a2c..b003d2156 100644 --- a/src/pages/contact.tsx +++ b/src/pages/contact.tsx @@ -1,11 +1,12 @@ import React from 'react'; import { graphql, PageProps } from 'gatsby'; import { ContactPage } from '../components/pages/contact/contact-page'; -import SEO from '../components/layout/seo'; +import SEO, { LocalesQueryProps } from '../components/layout/seo'; import { ContentfulPage } from '../types'; interface ContactPageQueryProps { contentfulPage: ContentfulPage; + locales: LocalesQueryProps; } const Contact = () => ; @@ -18,6 +19,7 @@ export const Head = ({ data, location }: PageProps) => { title={`${data.contentfulPage.title} | Satellytes`} description={data.contentfulPage.description?.description} location={location} + locales={data.locales} /> {/* * Styles and Script for Leaflet Hero Map diff --git a/src/pages/data-privacy.tsx b/src/pages/data-privacy.tsx index 04142d907..3d0081cbe 100644 --- a/src/pages/data-privacy.tsx +++ b/src/pages/data-privacy.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import SEO from '../components/layout/seo'; +import SEO, { LocalesQueryProps } from '../components/layout/seo'; import { graphql, PageProps } from 'gatsby'; import { Layout } from '../components/layout/layout'; import { ContentBlockContainer } from '../components/layout/content-block-container'; @@ -8,6 +8,7 @@ import { ContentfulPage, ContentfulRichTextType } from '../types'; interface DataPrivacyPageQueryProps { contentfulPage: ContentfulPage; + locales: LocalesQueryProps; } const DataPrivacyPage = ({ @@ -34,6 +35,7 @@ export const Head = ({ description={data.contentfulPage.seoMetaText} location={location} noIndex={true} + locales={data.locales} /> ); }; diff --git a/src/pages/imprint.tsx b/src/pages/imprint.tsx index c0dd69224..bc44f241f 100644 --- a/src/pages/imprint.tsx +++ b/src/pages/imprint.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import SEO from '../components/layout/seo'; +import SEO, { LocalesQueryProps } from '../components/layout/seo'; import { graphql, PageProps } from 'gatsby'; import { Layout } from '../components/layout/layout'; import { ContentBlockContainer } from '../components/layout/content-block-container'; @@ -8,6 +8,7 @@ import { ContentfulPage, ContentfulRichTextType } from '../types'; interface ImprintPageQueryProps { contentfulPage: ContentfulPage; + locales: LocalesQueryProps; } const ImprintPage = ({ data }: PageProps) => { @@ -29,6 +30,7 @@ export const Head = ({ data, location }: PageProps) => { description={data.contentfulPage.seoMetaText} location={location} noIndex={true} + locales={data.locales} /> ); }; diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 9e97fb056..b6860297a 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -1,6 +1,6 @@ import { graphql, PageProps } from 'gatsby'; import React from 'react'; -import SEO from '../components/layout/seo'; +import SEO, { LocalesQueryProps } from '../components/layout/seo'; import { Landingpage } from '../components/pages/landingpage/landingpage'; import { BlogPostTeaser, @@ -34,6 +34,7 @@ interface IndexPageQueryProps { careerHeader: ContentfulSectionHeader; servicesTeaser: ContentfulTeaser; blogHeader: ContentfulSectionHeader; + locales: LocalesQueryProps; } const IndexPage = ({ data }: PageProps) => { @@ -64,7 +65,12 @@ export default IndexPage; export const Head = ({ data, location }: PageProps) => { return ( <> - + ); diff --git a/src/pages/services.tsx b/src/pages/services.tsx index a17d85def..31bdb2c7f 100644 --- a/src/pages/services.tsx +++ b/src/pages/services.tsx @@ -1,6 +1,6 @@ import { graphql, PageProps } from 'gatsby'; import React from 'react'; -import SEO from '../components/layout/seo'; +import SEO, { LocalesQueryProps } from '../components/layout/seo'; import { Service } from '../components/pages/service/service'; import { ContentfulLeadBox, @@ -20,6 +20,7 @@ interface ServicesPageQueryProps { platformsList: ContentfulList; productsServicesList: ContentfulList; consultingList: ContentfulList; + locales: LocalesQueryProps; } const ServicesPage = ({ data }: PageProps) => { @@ -46,6 +47,7 @@ export const Head = ({ data, location }: PageProps) => { ); }; diff --git a/src/templates/blog-post-overview.tsx b/src/templates/blog-post-overview.tsx index c74a93940..72212bfbf 100644 --- a/src/templates/blog-post-overview.tsx +++ b/src/templates/blog-post-overview.tsx @@ -1,7 +1,7 @@ import { graphql, PageProps } from 'gatsby'; import React from 'react'; import { BlogOverviewPageContext } from '../../gatsby/create-pages/create-blog-post-overview-pages'; -import SEO from '../components/layout/seo'; +import SEO, { LocalesQueryProps } from '../components/layout/seo'; import { BlogPage } from '../components/pages/blog/blog-page'; import { IGatsbyImageData } from 'gatsby-plugin-image'; import { ContentfulSectionHeader } from '../types'; @@ -24,6 +24,7 @@ interface AllBlogPostsQuery { interface BlogPageQueryProps { allContentfulBlogPost: AllBlogPostsQuery; blogHeader: ContentfulSectionHeader; + locales: LocalesQueryProps; } const Blog = ({ @@ -48,6 +49,7 @@ export default Blog; export const Head = ({ pageContext, location, + data, }: PageProps) => { return ( ); }; diff --git a/src/templates/blog-post.tsx b/src/templates/blog-post.tsx index 8027425b5..e16ebbdf9 100644 --- a/src/templates/blog-post.tsx +++ b/src/templates/blog-post.tsx @@ -2,7 +2,7 @@ import { graphql, PageProps } from 'gatsby'; import { IGatsbyImageData } from 'gatsby-plugin-image'; import { useTranslation } from 'gatsby-plugin-react-i18next'; import React from 'react'; -import SEO from '../components/layout/seo'; +import SEO, { LocalesQueryProps } from '../components/layout/seo'; import { BlogPostPage } from '../components/pages/blog-post/blog-post'; import { BreadcrumbEntry, @@ -13,6 +13,7 @@ import { interface BlogArticleTemplateQueryProps { contentfulBlogPost: BlogArticleQueryData; contentfulLeadbox: ContentfulLeadBox; + locales: LocalesQueryProps; } const BlogArticleTemplate = ({ @@ -66,6 +67,7 @@ export const Head = ({ description={seoMetaText} location={location} rssLink + locales={data.locales} /> ); diff --git a/src/templates/career-details.tsx b/src/templates/career-details.tsx index e04ca033a..c99c1be29 100644 --- a/src/templates/career-details.tsx +++ b/src/templates/career-details.tsx @@ -1,7 +1,6 @@ import React from 'react'; -import SEO from '../components/layout/seo'; +import SEO, { LocalesQueryProps } from '../components/layout/seo'; import { graphql } from 'gatsby'; -import { useTranslation } from 'gatsby-plugin-react-i18next'; import { CareerDetails } from '../components/pages/career-details/career-details'; import { ContentfulVacancy } from '../types'; import { CareerDetailsStructuredData } from '../components/pages/career-details/career-details-structured-data'; @@ -18,6 +17,7 @@ interface CareerDetailsPageQueryProps { location: Location; data: { contentfulVacancy: ContentfulVacancy; + locales: LocalesQueryProps; }; } @@ -41,19 +41,24 @@ export const Head = ({ location, data }: CareerDetailsPageQueryProps) => { const socialCardPath = position.socialCardFile.childImageSharp.gatsbyImageData.images.fallback ?.src; - const { t } = useTranslation(); + + // Get translation + const dataLanguage = data.locales.edges.find( + (e) => e.node.ns === 'translations', + )?.node.data; + const t = JSON.parse(dataLanguage || '{}'); return ( <> From fa48e5a45b90d7f3b9b9455cf59e7e598eb19198 Mon Sep 17 00:00:00 2001 From: Wiebke Freitag Date: Wed, 6 Dec 2023 08:47:10 +0100 Subject: [PATCH 4/7] fix: correct alternate link --- src/components/layout/seo.tsx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/components/layout/seo.tsx b/src/components/layout/seo.tsx index b494c9cae..a93ec2050 100644 --- a/src/components/layout/seo.tsx +++ b/src/components/layout/seo.tsx @@ -1,6 +1,5 @@ import { graphql, useStaticQuery } from 'gatsby'; import React from 'react'; -import { useI18next } from 'gatsby-plugin-react-i18next'; import { I18nNextData } from '../../types'; import { DEFAULT_LANGUAGE, @@ -92,7 +91,6 @@ const SEO = ({ } } `); - const i18n = useI18next(); // Get translation const dataNode = locales.edges.find((e) => e.node.ns === 'translations') @@ -111,12 +109,12 @@ const SEO = ({ defaultLanguage: DEFAULT_LANGUAGE, path: location.pathname, }, - location.origin, + site.siteMetadata.siteUrl, ); return ( <> - + {title} {/* Standard Tags */} From fdd4a21e65b9ebf60c10ba86b64e35c006d32a64 Mon Sep 17 00:00:00 2001 From: Wiebke Freitag Date: Wed, 6 Dec 2023 09:41:32 +0100 Subject: [PATCH 5/7] feat: seo comment --- src/components/layout/seo.tsx | 13 +++++++++++-- src/templates/blog-post.tsx | 2 ++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/components/layout/seo.tsx b/src/components/layout/seo.tsx index a93ec2050..534f5b79e 100644 --- a/src/components/layout/seo.tsx +++ b/src/components/layout/seo.tsx @@ -21,6 +21,7 @@ interface SeoProps { location: Location; rssLink?: boolean; locales: LocalesQueryProps; + languages: string[]; } export interface LocalesQueryProps { @@ -79,6 +80,7 @@ const SEO = ({ location, rssLink, locales, + languages = LANGUAGES, }: SeoProps) => { const { site } = useStaticQuery(graphql` query { @@ -92,7 +94,14 @@ const SEO = ({ } `); - // Get translation + /** + * Gatsby Head API is not yet compatible to gatsby-plugin-react-i18next. + * Reference to solution/workaround to use translation in Head: + * https://github.com/gatsbyjs/gatsby/issues/36458 + * + * The i18n object (languages, language, originalPath, defaultLanguage) + * is replaced with constants and locales data for building the alternate meta tag. + */ const dataNode = locales.edges.find((e) => e.node.ns === 'translations') ?.node; const t = JSON.parse(dataNode?.data || '{}'); @@ -103,7 +112,7 @@ const SEO = ({ site.siteMetadata.siteUrl + (shareImagePath ?? DEFAULT_META_IMAGE_URL_PATH); const alternateLanguagesMetaTags = buildAlternateMetaTags( { - languages: LANGUAGES, + languages, language: (dataNode?.language as string) || DEFAULT_LANGUAGE, originalPath: location.pathname.replace('/de/', '/'), defaultLanguage: DEFAULT_LANGUAGE, diff --git a/src/templates/blog-post.tsx b/src/templates/blog-post.tsx index e16ebbdf9..fd6f3ec69 100644 --- a/src/templates/blog-post.tsx +++ b/src/templates/blog-post.tsx @@ -2,6 +2,7 @@ import { graphql, PageProps } from 'gatsby'; import { IGatsbyImageData } from 'gatsby-plugin-image'; import { useTranslation } from 'gatsby-plugin-react-i18next'; import React from 'react'; +import { DEFAULT_LANGUAGE } from '../../gatsby/config-options/constants'; import SEO, { LocalesQueryProps } from '../components/layout/seo'; import { BlogPostPage } from '../components/pages/blog-post/blog-post'; import { @@ -68,6 +69,7 @@ export const Head = ({ location={location} rssLink locales={data.locales} + languages={[DEFAULT_LANGUAGE]} /> ); From 49c290137ad3e310fbaf5069af525baf34ba75a5 Mon Sep 17 00:00:00 2001 From: Wiebke Freitag Date: Wed, 6 Dec 2023 11:12:45 +0100 Subject: [PATCH 6/7] fix: type error --- src/components/layout/seo.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/layout/seo.tsx b/src/components/layout/seo.tsx index 534f5b79e..87f6320a5 100644 --- a/src/components/layout/seo.tsx +++ b/src/components/layout/seo.tsx @@ -21,7 +21,7 @@ interface SeoProps { location: Location; rssLink?: boolean; locales: LocalesQueryProps; - languages: string[]; + languages?: string[]; } export interface LocalesQueryProps { From 3c9f246bcb09317293159d8f2257777a9494a091 Mon Sep 17 00:00:00 2001 From: Wiebke Freitag Date: Wed, 6 Dec 2023 11:28:48 +0100 Subject: [PATCH 7/7] fix: format error --- src/templates/blog-post.tsx | 52 +++++++++++++++----------------- src/templates/career-details.tsx | 18 +++++++---- 2 files changed, 36 insertions(+), 34 deletions(-) diff --git a/src/templates/blog-post.tsx b/src/templates/blog-post.tsx index fd6f3ec69..5c2262cb2 100644 --- a/src/templates/blog-post.tsx +++ b/src/templates/blog-post.tsx @@ -31,13 +31,11 @@ const BlogArticleTemplate = ({ ]; return ( - <> - - + ); }; @@ -50,28 +48,26 @@ export const Head = ({ const shareImagePath = heroImage.shareImage.resize.src; + /* + * SEO Notes: + * Recommended meta description length these days is 120 - 158 characters. The lower number is relevant for mobile devices. + * This means authored blog posts should always come with an explicit 120 character summary (`seoMetaText`). In case an author doesn't provide such a summary + * we will fallback to a generated excerpt fixed to the 158 characters to provide a little bit more text as the automatic extraction is usually + * less condense in terms of content. + */ return ( - <> - {/* - * SEO Notes: - * Recommended meta description length these days is 120 - 158 characters. The lower number is relevant for mobile devices. - * This means authored blog posts should always come with an explicit 120 character summary (`seoMetaText`). In case an author doesn't provide such a summary - * we will fallback to a generated excerpt fixed to the 158 characters to provide a little bit more text as the automatic extraction is usually - * less condense in terms of content. - */} - - + ); }; diff --git a/src/templates/career-details.tsx b/src/templates/career-details.tsx index c99c1be29..dc6c6adec 100644 --- a/src/templates/career-details.tsx +++ b/src/templates/career-details.tsx @@ -42,21 +42,27 @@ export const Head = ({ location, data }: CareerDetailsPageQueryProps) => { position.socialCardFile.childImageSharp.gatsbyImageData.images.fallback ?.src; - // Get translation + // Get translations const dataLanguage = data.locales.edges.find( (e) => e.node.ns === 'translations', )?.node.data; const t = JSON.parse(dataLanguage || '{}'); + const seoTitleDetails = t['career.seo.title-detail'].replace( + '{{name}}', + position.name, + ); + const seoDescriptionDetails = t['career.seo.description-detail'].replace( + '{{name}}', + position.name, + ); + return ( <>