How to manage SEO on your NextJS website with Strapi
Tags: nextjs, javascript, webdev, graphql
Published: 2022-04-07 03:04:47


### Introduction
Hey there friend, in this article, I will be explaining how to handle Search Engine Optimisation (SEO) on your [NextJS](https://nextjs.org/) website dynamically with [Strapi CMS](https://strapi.io/).

### Setup
The purpose of this article is not to teach you how to set up NextJS or Strapi on your local computer. So if you are new to these technologies, here are some useful links to get the projects up and running. 

_Strapi_ 
- Project setup [here](https://docs.strapi.io/developer-docs/latest/getting-started/quick-start.html#_1-install-strapi-and-create-a-new-project)

- Database configuration [here](https://docs.strapi.io/developer-docs/latest/setup-deployment-guides/configurations/required/databases.html#configuration-structure)

- Graphql Configuration [here](https://docs.strapi.io/developer-docs/latest/plugins/graphql.html)

_Next_
- Project setup [here](https://nextjs.org/docs#automatic-setup)

- Apollo Client Configuration [here](https://www.apollographql.com/blog/apollo-client/next-js/next-js-getting-started/)


Done with the setup? 

Let's set up content types on Strapi by following the following steps


1. Click on `Content-Type Builder` on the sidebar as shown in the image below

![Strapi dashboard indicating Content-Type Builder link on sidebar](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jg3inxyj613y21rwsaum.png)

2. Click on the `create new collection type` as shown in the image below

![Strapi Dashboard showing button to create collection type](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a103zs5kc5a04oi4c0ua.png)


Now that you know how to create a collection type, you would be creating two collection content types to manage seo for pages on your website. 

First create the `Seo Meta Tag` collection type which has two fields which include the following

![Image showing how to create seo meta tag collection type](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/frp94g88nlezaiszlbqf.png) 

- `property`: this is a text field. 
- `content`: this is also a text field

Next, create the `SEO` collection type which has two fields as well. 

![Image showing how to create seo collection type](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mzsr0sf7my3ihyf2am7g.png)
 
- `Title`: this is a text field.
- `seo_meta_tags`: this is a relation field where multiple  seo meta tags belong to a particular seo collection as shown in the image below 

![Image showing relationship between seo and seo meta tags](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h33w9021s2ql28n8fltg.png)

Now you are done creating collection types, you need to create a `single content-type` to manage content on your website pages. In this content types, you would add a relationship with the seo collection you have created. 


![Showing creation of single content type for home page](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ps0reeaoasluczce1ru5.png)


![Showing creation of relationship with Seo collection](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6amqft1seo234z8udycy.png)

Next up, you go to content manager on the sidebar and update all the content accordingly and publish them all so we can start coding.

But before we start, you need to enable public access to the content types. Therefore, you need to go to Settings -> Roles -> Public and enable `find` or/and `findOne` for all the content types you have created and save.

![Enabling public access](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1p1chksy3jeaonjvks9m.png)


Lets start coding!!!

First, You will create query needed to fetch data from strapi. Create a folder named `graphql` in your root directory and inside the graphql folder, create a file named `HomePageQuery.ts`. Inside the HomePageQuery.ts file, add the following code.

```ts
// /graphql/HomePageQuery.ts

import { gql } from "@apollo/client";

export default gql`
  # Write your query or mutation here
  query HomePage {
    homePage {
      data {
        attributes {
          seo {
            data {
              attributes {
                Title
                seo_meta_tags {
                  data {
                    attributes {
                      property
                      content
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
`;

```

Next up, replace the code in `/pages/index.tsx` with the following code 

```tsx
// /pages/index.tsx

import type { NextPage } from "next";
import client from "../apollo-client";
import query from "../graphql/HomePageQuery";

export async function getStaticProps() {
  const { data } = await client.query({
    query,
  });

  // data being fetched through the query. In this case we get the seo object which contains the title and meta tags 
  /**
   * content = {
   *    seo: {
   *      Title: <whatever title you set on strapi dashboard>,
   *      seo_meta_tags: {
   *        data: {attributes: {property: <set-data>, content: <set-data>}} 
   *      }
   *    }
   * }
   */
  const content = data.homePage.data.attributes;

  return {
    props: {
      content,
    },
  };
}

const Home: NextPage = () => {
  return <div></div>;
};

export default Home;

```

Because you passed the seo object in props in the `getStaticProps` method for the page, you can access it in `/pages/_app.tsx` through `pageProps` which allows you to now have a central point to manage seo data for all pages. Hence you would be updating the code in the said `/pages/_app.tsx` file with the following code: 

```tsx
// /pages/_app.tsx

import "../styles/globals.css";
import type { AppProps } from "next/app";
import Head from "next/head";

function MyApp({ Component, pageProps }: AppProps) {
  const seoDetails = pageProps?.content?.seo.data.attributes || {};

  return (
    <>
      <Head>
        <title>{seoDetails.Title}</title>
        {seoDetails.seo_meta_tags &&
          seoDetails.seo_meta_tags.data.map(({ attributes }: any, i: any) => (
            <meta key={i} {...attributes} />
          ))}
      </Head>
      <Component {...pageProps} />
    </>
  );
}

export default MyApp;


```

When you start your server and open the website on your web browser, you would notice the title of the page you updated has changed and you can also check the meta tags using developer tools.

## Conclusion
In this article we were able to create strapi and nextjs projects, we defined content types and added content, we were also able to add logic to the nextjs project to handle data from strapi. The code for this project can be found [here](https://github.com/haywhy43/nextjs-strapi-seo-tutorial). 

I understand it might be difficult to follow the article because it requires a lot of visual explanation, in which case I have decided to launch my [youtube channel](https://www.youtube.com/channel/UCroVFcOuelVGWemqgNZ2e0g). Help me get up to 50 subscribers and I would drop a video for further explanation on this article.

Dont forget to follow me on on [twitter](https://twitter.com/ayomikun_elijah) and [github](https://github.com/haywhy43) and also like and share my post.

Thanks.