Coder Social home page Coder Social logo

gatsby-plugin-wpgraphql-seo's Introduction

Gatsby SEO For WpGraphQL and Yoast

npm

Takes data from WpGraphQL and WPGraphQl Yoast SEO and provides you with Meta Tags and JSON+LD Schema in Gatsby.

Basic Setup

Install package

Yarn or NPM install

yarn add gatsby-plugin-wpgraphql-seo

or

npm install gatsby-plugin-wpgraphql-seo

Also, if you haven't already, install gatsby-plugin-react-helmet and react-helmet

yarn add gatsby-plugin-react-helmet react-helmet

or

npm install gatsby-plugin-react-helmet react-helmet

Find this useful?

Buy Me A Coffee

Setup Gatsby

Add gatsby-plugin-react-helmet to your plugins in gatsby-config, alongside any others you alrady have:

plugins: ['gatsby-plugin-react-helmet']

In your sites layout setup the context provider to pass the component your general site settings.

import React, { useState } from 'react';
import { useStaticQuery, graphql } from 'gatsby';
import { SEOContext } from 'gatsby-plugin-wpgraphql-seo';

export const Layout = () => {
    const {
        wp: { seo },
    } = useStaticQuery(graphql`
        query SiteInfoQuery {
            wp {
                seo {
                    contentTypes {
                        post {
                            title
                            schemaType
                            metaRobotsNoindex
                            metaDesc
                        }
                        page {
                            metaDesc
                            metaRobotsNoindex
                            schemaType
                            title
                        }
                    }
                    webmaster {
                        googleVerify
                        yandexVerify
                        msVerify
                        baiduVerify
                    }
                    schema {
                        companyName
                        personName
                        companyOrPerson
                        wordpressSiteName
                        siteUrl
                        siteName
                        inLanguage
                        logo {
                            sourceUrl
                            mediaItemUrl
                            altText
                        }
                    }
                    social {
                        facebook {
                            url
                            defaultImage {
                                sourceUrl
                                mediaItemUrl
                            }
                        }
                        instagram {
                            url
                        }
                        linkedIn {
                            url
                        }
                        mySpace {
                            url
                        }
                        pinterest {
                            url
                            metaTag
                        }
                        twitter {
                            username
                            cardType
                        }
                        wikipedia {
                            url
                        }
                        youTube {
                            url
                        }
                    }
                }
            }
        }
    `);

    return (
        <SEOContext.Provider value={{ global: seo }}>
            <p>... your layout</p>
        </SEOContext.Provider>
    );
};

Optionally you can pass options to the context via the options prop.

    const options = {
        schemaReplacement: {
                from: 'EXAMPLE';
                to: 'TO_REPLACE';
            }
    }
return (
        <SEOContext.Provider value={{ global: seo, options }}>
            <p>... your layout</p>
        </SEOContext.Provider>
    );

Currently this only supports the schemaReplacement option. This will replace the from value with the to value in the JSON+LD Schema.

For each page or template you then need to add the SEO Component

import React from 'react';
import { graphql } from 'gatsby';
import Seo from 'gatsby-plugin-wpgraphql-seo';

const Page = ({ data: { wpPage } }) => {
    return (
        <>
            <Seo post={wpPage} />
            <p>Rest of page</p>
        </>
    );
};

export default Page;

export const pageQuery = graphql`
    query GET_PAGE($id: String!) {
        wpPage(id: { eq: $id }) {
            nodeType
            title
            uri
            seo {
                title
                metaDesc
                focuskw
                metaKeywords
                metaRobotsNoindex
                metaRobotsNofollow
                opengraphTitle
                opengraphDescription
                opengraphImage {
                    altText
                    sourceUrl
                    srcSet
                }
                twitterTitle
                twitterDescription
                twitterImage {
                    altText
                    sourceUrl
                    srcSet
                }
                canonical
                cornerstone
                schema {
                    articleType
                    pageType
                    raw
                }
            }
        }
    }
`;

For archive pages

import React from 'react';
import { graphql } from 'gatsby';
import Seo from 'gatsby-plugin-wpgraphql-seo';

const Blog = ({ data }) => {
    return (
        <>
            <Seo
                title="Blog Title"
                postSchema={JSON.parse(
                    data.wp.seo.contentTypes.post.schema.raw
                )}
            />
            <p>Rest of page</p>
        </>
    );
};

export default Blog;

export const pageQuery = graphql`
      query GET_POSTS($ids: [String]) {
      
          wp {
            seo {
                contentTypes {
                    post {
                        schema {
                            raw
                        }
                    }
                }
            }

          }
          allWpPost(filter: { id: { in: $ids } }) {
            nodes {
              ...
            }
          }
           
    }
    `;

Additional props are provided for overrides and simpler pages:


    title: String to override Title
    meta: Array of key value objects for meta tags (e.g property, content)
    post: WpGrahpQL post object
    postSchema: JSON object to replace complete JSON+LD schema;

Removing search action from schema.

By default Yoast adds a search action to the schema if you want remove it you can add the following PHP to your functions.php file:

<?php
add_filter('wpseo_schema_website', 'XX_remove_schema_search');
function XX_remove_schema_search($data)
{
  if ($data['potentialAction']) {
    foreach ($data['potentialAction'] as $key => $value) {

      if ($value['@type'] && $value['@type'] == 'SearchAction') {
        unset($data['potentialAction'][$key]);
      }
    }
  }

  return $data;
}

... More docs coming soon

gatsby-plugin-wpgraphql-seo's People

Contributors

ashhitch avatar cloudbop avatar crock avatar joshdavenport avatar smujmaiku avatar thekishanraval avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

gatsby-plugin-wpgraphql-seo's Issues

custom permalink structure not recognized

Maybe not so much an issue as it is a discussion.

I changed WordPress' permalink structure to be /blog/%postname%, but when pulling the SEO data via graphql I don't see /blog/ reflected anywhere in there. As I am using this plugin for breadcrumbs as well I am technically missing a step in between "Home" and the blogpost title.

I've already downloaded the Yoast Test Helper plugin to clear its internal cache but that didn't help (helped to recognize permalink structure in the past, unrelated to Gatsby & this plugin).

In summary, the url pulled by the plugin correctly reflects the permalink structure, but I am only getting 2 objects in the array, instead of 3.

  "data": {
    "wpPost": {
      "seo": {
        "breadcrumbs": [
          {
            "text": "Home",
            "url": "/"
          },
          {
            "text": "Hello world!",
            "url": "/blog/hello-world/"
          }
        ]
      }
    }
  },

Is there any way to include "blog" in between Home and the blog post?

Error On Google Rich Results Test

Breadcrumbs are giving an incorrectly formatted URL in the ID field. My understanding is this must be a full URL, but it's just the slug (no scheme or hostname).

I may have misconfigured something though so wouldn't mind being advised if I have :)

Otherwise I love this, and have switched back to Yoast so I can use it :)

Lang attribute on multilanguage sites

I have a gatsby site with 2 languages (using wpml) and somehow the seo component only ever returns the first language in schema { inLanguage }.

Also it doesn't seem to add the lang attribute onto the html tag. Am I overlooking something here or do I need to add that one separately using React Helmet?

Old dependencies

Hi,

do you have any plans to upgrade gatsby-plugin-wpgraphql-seo dependency gatsby-plugin-image to the newest version. Problem is that Gatsby 5 requires React 18 while gatsby-plugin-image in version you're using needs React 16 or 17.

Meta property og:locale defaults to en_GB

Meta property og:locale defaults to en_GB

I tried adding meta={{property:"og:locale", content:"en_US"}} to Seo component, but that adds a second entry into head. There's now 1 for en_GB and 1 for en_US.

Is there a better way to override this?

Canonical URLs

This will be more a question than an issue. It seems that this library doesn't return a canonical tag. Does that sound right?

I ask because I installed this in a project, and I can't find the canonical tag, but I can find everything else in the Graphql query

Issue with meta prop

Hello, thank you for effort you are putting in this package.
I have a problem using meta prop, in README.md you said "meta: Array of key value objects for meta tags (e.g property, content)", but I'm not sure how to use it.
"meta={[{ metaDesc: "DESCRIPTION" }, { metaKeywords: ["KEYWORD"] }]}" - this doesn't work.

Gatsby Schema Update Breaking Change

The Gatsby specific Yoast WPGraphQL Schema seems to have updated several fields and is now breaking the GraphQL query, for instance the field contentTypes is no longer available. Seo is now embedded in each content type field (WpPost, WpPage, etc). As a result, the SEO parser is unable to map back to the proper schema and is resulting in breaking updates.

Please see the following issue with Gatsby GraphiQL
Screen Shot 2022-02-23 at 2 08 24 PM

Does not pull in any meta tags

Hey, this would be an amazing dependency, but somehow I can't get it to work. The meta tags always stay empty in and no description/title/etc is pulled from the server it seems.

GraphQL outputs this, which I want:
Screenshot 2022-03-04 at 6 42 53 PM

My layout component:

import React, { useEffect } from "react";
import { useStaticQuery, graphql } from "gatsby";
import { SEOContext } from "gatsby-plugin-wpgraphql-seo";

import Header from "./header";
import Footer from "./footer";
import "../styles/global.css";

export const Layout = (props) => {
  const {
    wp: { seo },
  } = useStaticQuery(graphql`
    query SiteInfoQuery {
      wp {
        seo {
          contentTypes {
            post {
              title
              schemaType
              metaRobotsNoindex
              metaDesc
            }
            page {
              metaDesc
              metaRobotsNoindex
              schemaType
              title
            }
          }
          webmaster {
            googleVerify
            yandexVerify
            msVerify
            baiduVerify
          }
          schema {
            companyName
            personName
            companyOrPerson
            wordpressSiteName
            siteUrl
            siteName
            inLanguage
            logo {
              sourceUrl
              mediaItemUrl
              altText
            }
          }
          social {
            facebook {
              url
              defaultImage {
                sourceUrl
                mediaItemUrl
              }
            }
            instagram {
              url
            }
            linkedIn {
              url
            }
            mySpace {
              url
            }
            pinterest {
              url
              metaTag
            }
            twitter {
              username
            }
            wikipedia {
              url
            }
            youTube {
              url
            }
          }
        }
      }
    }
  `);
  return (
    <SEOContext.Provider value={{ global: seo }}>
      <div className={props.class}>
        <Header />
        <div className="motion">
          {props.children}
          <Footer />
        </div>
      </div>
    </SEOContext.Provider>
  );
};

Then, my post template looks like this:

import React, { useEffect, useState } from "react";
import { graphql } from "gatsby";
import Seo from "gatsby-plugin-wpgraphql-seo";
import Layout from "../components/layout";
import "./post.css";

const PostTemplate = ({ data }) => {
  return (
    <>
      <Seo post={data.text.seo} />
      <Layout>
          <main>
                <h2>{data.text.title}</h2>
                <div
                  className="post__description"
                  dangerouslySetInnerHTML={{
                    __html: data.text.content,
                  }}
                />
          </main>
        </Layout>
    </>
  );
};

And my GraphQL query is like this:

export const query = graphql`
  query ($id: String!, $uri: String!) {
    text: wpPost(id: { eq: $id }) {
      title
      content
      seo {
        title
        metaDesc
        focuskw
        metaKeywords
        opengraphTitle
        opengraphDescription
        opengraphImage {
          sourceUrl
          srcSet
        }
        twitterTitle
        twitterDescription
        twitterImage {
          sourceUrl
          srcSet
        }
        canonical
        cornerstone
        schema {
          articleType
          pageType
        }
      }
    }
}

Where is my mistake?

Seems to require gatsby-plugin-react-helmet without stating so

Am I correct in that gatsby-plugin-react-helmet is required in order for this plugin to work? Wasn't getting any output in my static output and was going crazy until I added it. Totally makes sense that it's required in order for react-helmet to work and is obvious in hindsight but not having used helmet before, letalone in a Gatsby context so it just didn't occur to me.

If this is the case I think it should be stated in the docs - happy to PR if I'm right on this

Open Graph uses image url from WordPress installation

using WPGraphQL SEO plugin on my WordPress installation and have setup opengraph in Yoast.

However, open graph seems to be using sourceUrl as schema which results in URL from headless WordPress is being outputted instead of localFile. Is it possible to change?

Screenshot of issue: https://p221.p4.n0.cdn.getcloudapp.com/items/bLukQOjK/2233e2a6-2238-45c9-b76b-b541d8eceac1.png?v=af027efcf9df37008bd6593cd37b26d5

I have just copy/pasted the schema found in the documentation for gatsby-plugin-wpgraphql-seo

Compatible with gatsby 5.0.0?

Actually seems to be work on my local dev with gatsby 5.3.3, but not in Netlify because in dependences say:
"peerDependencies": {
"gatsby": "^3.0.0 || ^4.0.0",
"react": ">=16",
"react-helmet": "^6.1.0"
}
Is possible to add dependence from gatby 5.3.3 to be work on Netlify?

Investigate domain being removed from schema data

When the WP Source gatsby plugin imports data it converts all WP urls to relative ones but the schema requires one.

We need a way to insert this back in, maybe via a config option in the plugin

Umbrella issue for #10 and #2

options does not replace

I would like to replace the URL of my og:image and place it in the Gatsby static folder. Right now, it is loaded (and worse: displayed) with the full URL of my backend, that I'd like to hide.

const options = {
      schemaReplacement: {
              from: 'https://sub.url.com/';
              to: '';
          }
  }

This code does not seem to work and the full URL is displayed. How to fix this?

Screenshot 2022-03-19 at 11 19 37 AM

OpenGraph Image URLs point to WP instance, not static site instance

I have my WordPress install on a different subdomain, one which I'd prefer remained hidden (just because I don't want double indexed locations on Google).

The OpenGraph image URLs all give the hidden host as the scheme and hostname - whereas they should give the hostname where my site will be hosted. I suspect this would need to be a configuration item somewhere since the plugin wouldn't know.

site {
siteMetadata {
siteUrl
}
}

or something similar might work?

Remove "Discourage search engine indexing" from being set on the Gatsby site pages.

When you use this plugin with a headless wordpress instance, you don't want the WP instance to be indexed by search engines, so you tick checkbox in the WP ACP that says "Discourage search engine indexing". However, the problem comes when this Gatsby plugin carries over that setting to the Gatsby site, which should be indexed.

@ashhitch Is this something you would be open to being fixed if I open a PR for it? Should it be a configurable option in the gatsby-config?

options returns error

I would like to replace part of the url of my opengraph image, but get an error.

const Layout = (props) => {
  const {
    wp: { seo },
  } = useStaticQuery(graphql`
    query SiteInfoQuery {
      wp {
        seo {
          contentTypes {
            post {
              title
              schemaType
              metaRobotsNoindex
              metaDesc
            }
            page {
              metaDesc
              metaRobotsNoindex
              schemaType
              title
            }
          }
          webmaster {
            googleVerify
            yandexVerify
            msVerify
            baiduVerify
          }
          schema {
            companyName
            personName
            companyOrPerson
            wordpressSiteName
            siteUrl
            siteName
            inLanguage
            logo {
              sourceUrl
              mediaItemUrl
              altText
            }
          }
          social {
            facebook {
              url
              defaultImage {
                sourceUrl
                mediaItemUrl
              }
            }
            instagram {
              url
            }
            linkedIn {
              url
            }
            mySpace {
              url
            }
            pinterest {
              url
              metaTag
            }
            twitter {
              username
            }
            wikipedia {
              url
            }
            youTube {
              url
            }
          }
        }
      }
    }
  `);
  const options = {
      schemaReplacement: {
              from: 'https://sub.url.com/';
              to: 'https://url.com/';
          }
  }
  return (
    <SEOContext.Provider value={{ global: seo, options }}>
      <div className={props.class}>
        <Header />
        <div>
          {props.children}
          <Footer />
        </div>
      </div>
    </SEOContext.Provider>
  );
};

This returns an error: Unexpected token, expected ",". Using commas instead fixes the error but then "sub.url.com" stays "sub.url.com" and does not change to "url.com".

Allow Schema Arrays in SEO

The json-ld spec specifies "... an array of zero or more node objects." However, the postSchema property in the SEO component doesn't allow for an array of schema. Instead an array is converted to an Object:

{"0": { ... }, "1": { ... }}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.