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.
Ingeniero en Informática, me encanta crear cosas o arreglarlas y darles una nueva vida. Escritor y poeta. Más de 20 APPs publicadas y un libro en Amazon.