Blog   ❯   Author: Fabio MoschiniDate: 02.09.2022

Site layout

alt text for image

Working on the Layout

In this article, we'll see how to make our blog a bit more appealing by working on the layout. We'll add a header, footer, navigation bar, and in general, we'll see how to create reusable components.
Specifically, we'll define:
  • - a component that implements the Header, within which we'll position the site header and, just below it, the navigation bar to move between pages;
  • - another component for the Footer, where we'll put, for example, contact information;
  • - finally, a Layout component that encapsulates both the Header and Footer components, so we can use only this one in the blog pages.

Prerequisites

We need to install some plugins that will facilitate the development of the site for aspects concerning stylesheets and the use of specific fonts.
Let's start by installing the gatsby-plugin-sassplugin with the command:
npm install sass gatsby-plugin-sass
Then, let's modify the gatsby-config.js file and add the `gatsby-plugin-sass` entry within the plugins section. Through this addition, we can write our stylesheets in a file with.scss extension and import it like any other component. Let's also install the gatsby-plugin-google-fonts plugin with the command:
npm install gatsby-plugin-google-fonts
to use Google Fonts: for our blog, we'll use the Roboto font, so we'll specify these settings in the gatsby-config.jsfile (in the plugin section):
{ resolve: `gatsby-plugin-google-fonts`, options: { fonts: [ `roboto` ], display: 'swap' } }

Header Component

To structure the source code in an orderly way, let's create a directory that will contain the components. Inside the srcdirectory, let's create the componentsdirectory and, inside it, create these files:
  • - header.js: will contain the code to define the Header component;
  • - header.module.scss: is the style sheet with the stylesheets used by header.js:
alt text for image


Inside the header.js file, let's insert this code:

import * as React from "react" import { Link } from "gatsby" import { graphql } from "gatsby" import { useStaticQuery } from 'gatsby' import * as styles from "./header.module.scss" export default function Header() { const data = useStaticQuery(headerQuery) const { title, description, author } = data.site.siteMetadata return ( <> <header className={styles.header}> <Link className={styles.linkHome} to="/"> <p className={styles.title}>{title} - {author}</p> <p className={styles.description}>{description}</p> </Link> <div className={styles.menu}> <ul className={styles.navigation}> <li><Link to="/" activeClassName={styles.navigationActive} className={styles.navigation}>Home</Link></li> <li><Link to="/about/" activeClassName={styles.navigationActive} className={styles.navigation}>About</Link></li> </ul> </div> </header> </> ) } const headerQuery = graphql` query headerQuery { site { siteMetadata { title description author } } } ` }
In the header.module.scss file, let's insert this code:
.header { background-color: #0d4faa; font-family: Roboto; padding-top: 10px; padding-bottom: 10px; padding-left: 20px; padding-right: 20px; } .linkHome { color: #d9e9f1; text-decoration: none; } .title { font-family: Roboto; font-size: 24pt; font-weight: bold; margin: 0px; } .description { font-family: Roboto; font-size: 16pt; margin: 0px; } .menu { font-family: Roboto; color: #ffffff; background-color: #444444; margin-top: 10px; } ul.navigation { list-style-type: none; margin-left: 0px; margin-right: 0px; overflow: hidden; background-color: #358b5c; margin-block-start: 0px; margin-block-end: 0px; padding-inline-start: 0px; } ul.navigation > li { display: block; float: left; } .navigation { text-decoration: none; color: white; } ul.navigation > li a { display: block; color: white; text-align: center; text-decoration: none; padding: 14px 16px; font-size: 22px; } ul.navigation > li a:hover { background-color: rgb(145, 218, 131); } .navigationActive { background-color: rgb(112, 172, 104); }

Footer Component

Similarly to what we did for the Header component, in the components directory let's create the files:
  • - footer.js: will contain the code to define the Footer component;
  • - footer.module.scss: is the style sheet with the stylesheets used by footer.js:
alt text for image


Inside the footer.js file, let's insert this code:
import * as React from "react" import { graphql } from "gatsby" import { useStaticQuery } from 'gatsby' import * as styles from "./footer.module.scss" export default function Footer() { const data = useStaticQuery(footerQuery) const { title, author } = data.site.siteMetadata return ( <footer className={styles.footer}> <div> <h1> <div className={styles.text}> 2022 - {author} - {title} </div> <div className={styles.text}> <a href="mailto:info@moschini.cloud"> info@moschini.cloud </a> </div> </h1> </div> </footer> ) } const footerQuery = graphql` query footerQuery { site { siteMetadata { title author } } } `

In the footer.module.scss file, let's insert this code:

.footer { background-color: #b1c7e6; margin-top: 30px; font-family: Roboto; padding-top: 10px; padding-bottom: 10px; padding-left: 20px; padding-right: 20px; position: relative; bottom: 0; } .text { color: rgb(7, 93, 133); text-decoration: none; font-family: Roboto; font-size: 14pt; font-weight: normal; text-align: center; }

Layout Component

Finally, for the Layout component, in the components directory let's create the files:
  • - layout.js: will contain the code to define the Layout component;
  • - layout.module.scss: is the style sheet with the stylesheets used by layout.js:
alt text for image


whose content is:

layout.js:
import * as React from "react" import PropTypes from "prop-types" import Header from "./header" import Footer from "./footer" import * as styles from "./layout.module.scss" const Layout = ({ children }) => { return ( <> <Header> </Header> <div className={styles.maincontent}> <main> {children} </main> </div> <Footer> </Footer> </> ) } Layout.propTypes = { children: PropTypes.node.isRequired } export default Layout

layout.module.scss:
* { box-sizing: border-box; } .maincontent { margin-top: 0px; margin-bottom: 0px; margin-left: 150px; margin-right: 150px; font-family: Roboto; }

Using the Layout Component

At this point, we have what we need to standardize the layout of all blog pages. Let's start with the home page, that is, the index.js file, whose code we'll replace with this:
import React from "react" import { graphql } from "gatsby" import { Link } from 'gatsby' import Layout from "../components/layout" export default function Home({ data }) { const { title, description, author } = data.site.siteMetadata return ( <div> <Layout> <h1>{title}</h1> <p>{description}</p> <p>{author}</p> <Link to="about">About</Link> </Layout> </div> ) } export const pageQuery = graphql` query MetadataQuery { site { siteMetadata { title description author } } } `

The differences from the previous version concern:
  • - importing the Layout component
  • - its use through the tags <Layout> ... </Layout>: what we've put between the opening and closing tags is the page content, so any further code additions must be made within the <Layout> ... </Layout> section. This way, if all site pages use the Layout component, we'll have complete uniformity of the visual interface.

Similarly, the code for the About page (file: about.js) will be modified as follows:

import * as React from "react" import { StaticImage } from "gatsby-plugin-image" import Layout from "../components/layout" const About = () => ( <div> <Layout> <h1>Mi chiamo Fabio Moschini e sono un programmatore.</h1> <p>Puoi inviarmi una email a questo indirizzo: <a href="mailto:info@moschini.cloud"> info@moschini.cloud </a> </p> <StaticImage layout="fullWidth" alt="notebook" src="../images/notebook.jpg" /> </Layout> </div> ) export default About
In this case too, all the page content is enclosed between the<Layout> ... </Layout> tags. The final result is:
alt text for image

alt text for image