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.
