Frontend Serverless with React and GraphQL

Start at the beginning and work your way through this project. The code for each step as well as the finished project can be found in the Github repository.


6. Add MainHead component

Objective: Add a html head to our project with a page title and favicon.

We will pick back up with building out our <MainLayout> component by adding the html head tags. Next.js provides a head component that we will use and inside of it we will add all the typical <title>, <meta>, and <link> tags that you'd expect in a html document.

Start by creating a <MainHead> component inside the component/layout/MainLayout.tsx file. Inside it, first add the <title> tag and pass in a variable title into the function which will be a string. Next, we can set the charset, viewport, description, keyword, and author, followed by the og social media tags.

Next, we need to add the favicons which will show up in browser tags. Download the zip file at the bottom of this lecture and unzip the contents to the public folder in the root of your project.

components/layout/MainLayout.tsx

import { ThemeProvider } from 'styled-components';
import { Component, ReactNode } from 'react';
import { theme } from '../../utils/theme';
import { GlobalStyle } from '../../utils/globalStyle';
import Head from 'next/head';
const MainHead = ({ title }: { title: string }) => (
<Head>
<title>{title}</title>
<meta charSet="utf-8" />
<meta name="viewport" content="initial-scale=1.0, width=device-width" />
<meta
name="description"
content="A recipe discovery app powered by Next.js."
/>
<meta name="author" content="codemochi" />
<meta name="keyword" content="next, react, typescript, js" />
<meta property="og:type" content="website" />
<meta property="og:title" content={title} />
<meta property="og:url" content="https://next-chop.codemochi.com" />
<meta property="og:image" content="/logo.svg" />
<meta
property="og:description"
content="A recipe discovery app powered by Next.js."
/>
<link
rel="apple-touch-icon"
sizes="180x180"
href="/favicon/apple-touch-icon.png"
/>
<link
rel="icon"
sizes="32x32"
type="image/png"
href="/favicon/favicon-32x32.png"
/>
<link
rel="icon"
sizes="16x16"
type="image/png"
href="/favicon/favicon-16x16.png"
/>
<link rel="manifest" href="/favicon/site.webmanifest" />
</Head>
);
type Props = {
children: ReactNode;
title?: string;
};
export class MainLayout extends Component<Props> {
render() {
const { title, children } = this.props;
return (
<ThemeProvider theme={theme}>
<MainHead title={title} />
<GlobalStyle />
{children}
</ThemeProvider>
);
}
}

Now we have to update our pages/index.tsx file so that we are passing a prop title into our <MainLayout> component:

pages/index.tsx

import styled from 'styled-components';
import { MainLayout } from '../components/layout/MainLayout';
const StyledHeader = styled.h1`
${({ theme }) => `
font-size: 2em;
text-align: left;
padding: ${theme['padding-small']} ${theme['padding-small']};
`}
`;
const Index = () => {
return (
<MainLayout title="Recipes">
<StyledHeader>Index Page</StyledHeader>
</MainLayout>
);
};
export default Index;

Make sure that both the title and favicons are working properly before you move onto the next step. You might have to start and stop the server for all of the files to properly load. If they are still giving you problems, feel free to move on and then check back later- certain browsers can sometimes cache favicons so they can be slow to change or update.