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

Tiempo de lectura: 2 minutos

Hoy vamos a aprender una forma de crear un componente Head que se repita en nuestras páginas y nos sirva para personalizar cada página que visitamos, de forma que se construya sobre un Server Side Render (SSR).

Lo primero que vamos a hacer es crearnos un objeto con los atributos que vamos a pasar a nuestro Head:

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

El código está en TypeScript, si necesitas pasarlo a JavaScript deberás eliminar los tipos.

Ahora tenemos que crear un componente que tendrá nuestro Head, lo llamaremos Head.tsx incluimos lo siguiente:

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

interface Props {
  headerObj?: HeadObj;
}

function HeadComponent({ headerObj } : Props) {
  return (
    <Head>
      {/* Meta común */}
      <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?.descripcion} />
      <meta name="keywords" content={headerObj?.keywords} />

    </Head>
  );
}

export default HeadComponent;

Es un Head muy sencillo, pero podremos poner todas las propiedades que necesitemos.

Ahora para que funcione de forma limpia y en todas las páginas vamos a incluirlo usando un context mediante un Service Provider.

Lo he llamado UtilsContext.tsx

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

// Crear el contexto
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>
    );
};

Ahora importamos el contexto o service provider, para ello tenemos que ir al archivo o crearlo dentro de pages, llamado _app.tsx añadimos el siguiente código:

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

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

export default MyApp;

Y ahora ya está preparado para usarse en cualquiera de nuestras pages.

Por ejemplo en index.tsx

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

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

  return (
    <div>
      <h1>Mi página principal</h1>
    </div>
  );
};

export default Home;

export async function getServerSideProps() {
  // Crear el objeto de encabezado
  const headerObj: HeadObj = {
    title: "Mi página principal, titulo cambiado",
    description: "descripcion",
    keywords: "indexKeywords",
  };

    return {
      props: {
        headerObj: headerObj, // Pasar el objeto de encabezado
      },
    };
 
}

Y con esto rellenará el título y atributos del SEO de nuestra página.

Lo he puesto en getServerSideProps para que lo haga en tiempo de ejecución, pero puedo ponerlo en getStaticProps para que lo obtenga de forma estática.

Deja un comentario