In this section, we'll learn how to create a template layout in Gatsby. In the template, the header and footer of the website remain unchanged and the body components change depending on the data or slug. You can clone the below repo code to follow along.
You can view the final code in the repository below.
In the Gatsby framework, any .js
file is located at src/pages
served as the route in the browser. We can refer to the src/pages
files as Page components.
The file located at src/component
is a simple React component and does not serve as a page route in the browser. We can import the src/component
react component into the Page component to create the UI.
For the layout template, we can create the file at the below location:
src/components/layout.js
In the layout.js
, we can write the code as below:
import React from "react"
const Layout = ({ location, children }) => {
return (
<>
<span>Header</span>
<main>{children}</main>
<span>Footer</span>
</>
)
}
export default Layout
The layout.js
is a simple React component. We can import the layout.js
component inside the Page component to use in different routes. For example, the homepage route file is located at the below location
/src/pages/index.js
In the index.js
, we can write the code as below:
import React from "react"
import Layout from "@components/layout"
const BlogIndex = ({ data, location }) => {
return <Layout location={location}>This is main content.</Layout>
}
export default BlogIndex
If we now visit the localhost page, the below page is rendered.
For the header and footer, we can create the React component at the below location:
src/components/header.js
src/components/footer.js
In the layout component, we can update the code in layout.js
as below.
import React from "react"
import Header from "@components/header"
import Footer from "@components/footer"
const Layout = ({ location, children }) => {
return (
<>
<Header location={location} />
<main className="container max-w-2xl px-5 py-10 mx-auto">{children}</main>
<Footer />
</>
)
}
export default Layout
In the above layout.js
code, we import the Header
and Footer
React components and pass the content of the main body in the children's props of the Layout component.
In the header, we need to import an image of the logo. For that, we can place the logo image file in the Gatsby project at the below location.
/static/avatar.png
Please note that any files located in the static folder serve after the /
route in Gatsby Project.
You can download the avatar logo below.
For example, the avatar.png
serves at the below route:
http://localhost:8000/avatar
View the below image for your reference.
For the Header component, we can create a file at the below location.
src/components/header.js
In the header.js
, we can write the code as below.
import React from "react"
import { Link } from "gatsby"
export default function Header({ location }) {
return (
<header className="container max-w-2xl px-3 pt-10 mx-auto">
<nav
className="relative flex items-center justify-between sm:h-10"
aria-label="Global"
>
<div className="flex items-center flex-grow flex-shrink-0 lg:flex-grow-0">
<div className="flex items-center justify-between w-full md:w-auto">
<a href="/">
<span className="sr-only">Author</span>
<img
className="w-auto h-10"
src="/avatar.png"
alt="avatar"
loading="lazy"
/>
</a>
</div>
</div>
<div className="md:block md:ml-10 md:pr-4 md:space-x-8">
<Link
className={
location.pathname === "/"
? "font-medium text-blue-500"
: "hover:text-blue-800"
}
to="/"
>
Home
</Link>
<Link
className={
location.pathname === "/product"
? "font-medium text-blue-500"
: "hover:text-blue-800"
}
to="/product"
>
Product
</Link>
<Link
className={
location.pathname === "/contact"
? "font-medium text-blue-500"
: "hover:text-blue-800"
}
to="/contact"
>
Contact
</Link>
<Link
className={
location.pathname === "/login"
? "font-medium text-blue-500"
: "hover:text-blue-800"
}
to="/login"
>
Login
</Link>
</div>
</nav>
<div className="flex py-3 text-sm font-medium border-b nav"></div>
</header>
)
}
Below we break down how the Header component code works.
The above Header component renders in the localhost browser as below:
In the Header
component, we have the following navigation pages:
Home, Product , Contact, Login
For the header component, the active navigation link is highlighted as shown below.
We can get the information on the active navigation through the location props of the Page component as shown below.
In our case, the page component is HomePage located at src/pages/index.js
. The layout.js
and header.js
component is a simple React component. We can get location props from the page component, and then pass the location props from the Page component to the React component as shown in the below image.
We can extract the below information from the location Props:
{
"pathname":"/",
"search":"",
"hash":"",
"href":"http://localhost:8000/",
"origin":"http://localhost:8000",
"protocol":"http:",
"host":"localhost:8000",
"hostname":"localhost",
"port":"8000",
"state":null,
"key":"initial"
}
Each of the navigation pages has a unique slug. We can use the Location props to highlight the active navigation tab in the header as shown in the below code.
We use Tailwind to style the Header component. To visualize it, you can view the below GIF.
In the above, we use inspectflow tool to enable and disable Tailwind utility classes.
The Footer component has a basic UI and we can style it using Tailwind. For the footer component, we can create the file at the below location.
src/components/footer.js
In the footer.js
, we can write the code as below:
import React from "react"
export default function Footer({ location }) {
return (
<footer className="w-full border-t border-red-500 p-6 text-center pin-b">
<p>
Created by <a href="https://taimoorsattar.dev">Taimoor Sattar</a> •
© 2021
</p>
</footer>
)
}
The footer component preview in the browser as below:
Great! We can now use the template layout component on different Page components.