From 7fbab58d91ea244ab0974ec12bcf0b185bdcec9b Mon Sep 17 00:00:00 2001 From: Jimmy Andrade Date: Thu, 16 Jul 2026 13:59:10 -0300 Subject: [PATCH] fix(seo): default description and title from site metadata metax SEO marks description as required; IndexTemplate and other pages often omit it. The local SEO wrapper now falls back to useSiteMetadata(), IndexTemplate passes an explicit home description, and TROUBLESHOOTING documents the warning. Upstream metax fix: muy/muy#154 / muy/muy#155. Closes #455 Co-authored-by: Cursor --- TROUBLESHOOTING.md | 16 ++++ src/components/SEO/index.js | 144 ++++++++++++++++--------------- src/components/SEO/index.test.js | 65 ++++++++++++++ src/templates/index.js | 1 + 4 files changed, 157 insertions(+), 69 deletions(-) create mode 100644 src/components/SEO/index.test.js diff --git a/TROUBLESHOOTING.md b/TROUBLESHOOTING.md index a1595923..503aa577 100644 --- a/TROUBLESHOOTING.md +++ b/TROUBLESHOOTING.md @@ -304,6 +304,22 @@ Given `npm install` / `npm ci` floods the terminal with `npm warn deprecated … 3. Prefer fixing/removing those roots over adding an `override` per leaf package; 4. Keep using Node 18 + `npm install --legacy-peer-deps` for this stack. +## Jest PropTypes: SEO required `description` undefined + +Given the browser console shows: + +``` +Warning: Failed prop type: The prop `description` is marked as required in `SEO`, but its value is `undefined`. + at SEO (…/metax/…) + at SEO (src/components/SEO/…) + at IndexTemplate (src/templates/index.js) +``` + +1. Ensure `src/components/SEO` defaults `description` (and `title`) from `useSiteMetadata()` when omitted; +2. Prefer page-specific `description` on important routes (e.g. home `IndexTemplate`); +3. Upstream: [muy/muy#154](https://github.com/muy/muy/issues/154) / PR for `metax` `mergeProps` fallback; +4. See #455. + ## Gatsby HMR eslint-loader: unused vars / anonymous page exports Given the browser console (or terminal) shows eslint-loader module warnings such as: diff --git a/src/components/SEO/index.js b/src/components/SEO/index.js index 1e6690d1..445b6def 100644 --- a/src/components/SEO/index.js +++ b/src/components/SEO/index.js @@ -2,74 +2,80 @@ import React from "react" import { SEO as MetaxSEO } from "metax" import useSiteMetadata from "../../hooks/useSiteMetadata" -const SEO = (props) => ( - -) +const SEO = ({ description, title, ...props }) => { + const siteMetadata = useSiteMetadata() + + return ( + + ) +} export default SEO diff --git a/src/components/SEO/index.test.js b/src/components/SEO/index.test.js new file mode 100644 index 00000000..3860a3e4 --- /dev/null +++ b/src/components/SEO/index.test.js @@ -0,0 +1,65 @@ +import React from "react" +import { render } from "@testing-library/react" +import SEO from "." + +jest.mock("../../hooks/useSiteMetadata", () => () => ({ + description: "Site default description", + title: "Multei!", + titleTemplate: "%s | Multei!", +})) + +const mockMetaxSEO = jest.fn(() => null) + +jest.mock("metax", () => ({ + SEO: (props) => { + mockMetaxSEO(props) + return null + }, +})) + +describe("", () => { + beforeEach(() => { + mockMetaxSEO.mockClear() + }) + + it("defaults description and title from site metadata", () => { + const consoleError = jest + .spyOn(console, "error") + .mockImplementation(() => {}) + + render() + + expect(mockMetaxSEO).toHaveBeenCalledWith( + expect.objectContaining({ + description: "Site default description", + title: "Multei!", + }) + ) + + const descriptionWarnings = consoleError.mock.calls.filter((args) => + args.some( + (arg) => + typeof arg === "string" && + arg.includes("prop `description` is marked as required") + ) + ) + expect(descriptionWarnings).toHaveLength(0) + consoleError.mockRestore() + }) + + it("prefers explicit description and title props", () => { + render( + + ) + + expect(mockMetaxSEO).toHaveBeenCalledWith( + expect.objectContaining({ + description: "Page-specific description", + title: "Denunciar estacionamento irregular", + }) + ) + }) +}) diff --git a/src/templates/index.js b/src/templates/index.js index e1beb617..f4c430fa 100644 --- a/src/templates/index.js +++ b/src/templates/index.js @@ -15,6 +15,7 @@ const IndexTemplate = () => { return (