Crear un Head dinámico con Next.js y establecerlo en Server Side Render (SSR)

Tiempo de lectura: 2 minutos

Today we are going to learn a way to create a Head component that repeats on our pages and serves to customize each page we visit, so that it is built on a Server Side Render (SSR).

The first thing we are going to do is create an object with the attributes that we are going to pass to our Head:

export interface HeadObj {
    title: string;
    description: string;
    keywords: string;
}

The code is in TypeScript, if you need to pass it to JavaScript you must remove the types.

Now we have to create a component that will have our Head, we will call it Head.tsx including the following:

import { HeadObj } from '@/objects/Page';
import Head from 'next/head';
import React from 'react';

interface Props {
  headerObj?: HeadObj;
}

function HeadComponent({ headerObj } : Props) {
  return (
    <Head>
      {/* Common Meta */}
      <title>{headerObj?.title}</title>
      <meta httpEquiv="Content-Type" content="text/html; charset=UTF-8" />
      <meta content="IE=edge" httpEquiv="X-UA-Compatible" />
      <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport" />
      <meta name="description" content={headerObj?.description} />
      <meta name="keywords" content={headerObj?.keywords} />

    </Head>
  );
}

export default HeadComponent;

It is a very simple Head, but we can put all the properties we need.

Now, to make it work cleanly and on all pages, we are going to include it using a context through a Service Provider.

I have called it UtilsContext.tsx

// context/ServiceContext.tsx
import HeadComponent from '@/components/Head';
import React, { createContext, useContext } from 'react';

// Create context
const UtilsContext = createContext<{
}  undefined>(undefined);

export const UtilsProvider: React.FC<{ children: React.ReactNode, headerObj: any }> = ({ children, headerObj }) => {
    return (
        <UtilsContext.Provider
            value={
                {

                }}>
            <HeadComponent headerObj={headerObj} />
            {children}
        </UtilsContext.Provider>
    );
};

Now we import the context or service provider, for this we have to go to the file or create it inside pages, called _app.tsx add the following code:

// pages/_app.tsx
import React from 'react';
import { AppProps } from 'next/app';
import { UtilsProvider } from '@/context/UtilsContext';

const MyApp: React.FC = ({ Component, pageProps }) => {
  const { headerObj, ...rest } = pageProps;
  return (
      <UtilsProvider headerObj={headerObj}>
        <Component {...rest} />
      </UtilsProvider>
  );
};

export default MyApp;

And now it is ready to be used in any of our pages.

For example in index.tsx

// src/app/page.tsx
import React, { use, useEffect } from 'react';
import { HeadObj } from '@/objects/Page';

const Home: React.FC = ({ }) => {

  return (
    <div>
      <h1>My main page</h1>
    </div>
  );
};

export default Home;

export async function getServerSideProps() {
  // Create header object
  const headerObj: HeadObj = {
    title: "My main page, changed title",
    description: "description",
    keywords: "indexKeywords",
  };

    return {
      props: {
        headerObj: headerObj, // Pass the header object
      },
    };
 
}

And with this it will fill in the title and SEO attributes of our page.

I have put it in getServerSideProps so that it does it at runtime, but I can put it in getStaticProps so that it gets it statically.

Leave a Comment