Gatsby is a static web site framework that’s based on React.
We can use it to create static websites from external data sources and more.
In this article, we’ll look at how to create a site with Gatsby.
Scroll Restoration
We can restore the scrolling position after refresh with Gatsby.
For example, we can write:
import React from "react"
import { useScrollRestoration } from "gatsby"
const IndexPage = () => {
const ulScrollRestoration = useScrollRestoration(`page-component-ul-list`)
return (
<ul style={{ height: 200, overflow: `auto` }} {...ulScrollRestoration}>
{Array(100).fill().map((_, i) => i).map(n => (
<li key={n}>{n}</li>
))}
</ul>
)
}
export default IndexPage
We use the useScrollRestoration hook with the 'page-component-ul-list' argument to let us create an object to restore the scrolling position.
Then we spread that object’s properties as props of the ul to let us restore the scrolling position.
Location Data from Props
We can get location data from props.
To do this, we write:
gatsby-config.js
module.exports = {
siteMetadata: {
siteURL: 'http://example.com'
}
}
src/pages/foo.js
import React from "react"
import { graphql } from "gatsby"
const FooPage = ({ location, data }) => {
const canonicalUrl = data.site.siteMetadata.siteURL + location.pathname
return <div>The URL of this page is {canonicalUrl}</div>
}
export const query = graphql`
query PageQuery {
site {
siteMetadata {
siteURL
}
}
}
`
export default FooPage
We get the siteMetadata.siteURL from the gatsby-config.js via the GraphQL query.
Then we get the location prop’s pathname property to get the path to the FooPage .
So we should see:
The URL of this page is http://example.com/foo
displayed when we go to http://localhost:8000/foo.
Providing State to a Link Component
We can provide state to a Link component.
For example, we write:
src/pages/index.js
import { Link } from "gatsby"
import React from "react"
const IndexPage = () => {
return <>
<div>hello world</div>
<Link
to={'/foo'}
state={{ id: 1 }}
>
go to foo
</Link>
</>
}
export default IndexPage
src/pages/foo.js
import React from "react"
const FooPage = ({ location }) => {
const { state = {} } = location
const { id } = state
return <div>id: {id}</div>
}
export default FooPage
We pass an object into the state prop.
Then in FooPage , we get the location prop’s state.id property to get the id property that we passed into the state prop.
Dynamic Navigation
We can add navigation dynamically with Gatsby.
To do this, we write:
module.exports = {
siteMetadata: {
title: 'Gatsby Starter',
menuLinks: [
{
name: 'home',
link: '/'
},
{
name: 'foo',
link: '/foo'
}
]
},
plugins: []
}
src/components/layout.js
import React from "react"
const { StaticQuery, Link } = require("gatsby");
const Header = ({ siteTitle, menuLinks }) => (
<header
style={{
background: "green",
marginBottom: "1.45rem",
}}
>
<div>
<h1 style={{ margin: 5, flex: 1 }}>
<Link
to="/"
style={{
color: "white",
textDecoration: "none",
}}
>
{siteTitle}
</Link>
</h1>
<div>
<nav>
<ul style={{ display: "flex", flex: 1 }}>
{menuLinks.map(link => (
<li
key={link.name}
style={{
listStyleType: `none`,
padding: `1rem`,
}}
>
<Link style={{ color: `white` }} to={link.link}>
{link.name}
</Link>
</li>
))}
</ul>
</nav>
</div>
</div>
</header>
)
const Layout = ({ children }) => (
<StaticQuery
query={graphql`
query SiteTitleQuery {
site {
siteMetadata {
title
menuLinks {
name
link
}
}
}
}
`}
render={data => (
<>
<Header menuLinks={data.site.siteMetadata.menuLinks} siteTitle={data.site.siteMetadata.title} />
<div
style={{
margin: '0 auto',
maxWidth: 960,
padding: '0px 1.0875rem 1.45rem',
paddingTop: 0,
}}
>
{children}
</div>
</>
)}
/>
)
export default Layout;
src/pages/index.js
import { Link } from "gatsby"
import React from "react"
import Layout from "../components/layout"
const IndexPage = () => {
return <>
<Layout>
<div>hello world</div>
</Layout>
</>
}
export default IndexPage
src/pages/foo.js
import React from "react"
import Layout from "../components/layout"
const FooPage = () => {
return <div>
<Layout>
<div>foo</div>
</Layout>
</div>
}
export default FooPage
We add the menuLinks array into gatsby-config.js to add the data for the links.
Then in layout.js , we get the link data and then render them.
The Header component takes the siteTitle and menuLinks props and render the data into HTML.
siteTitle has the title of the site.
menuLinks is an array of data that we have from gatsby-config.js ‘s menuLinks property.
Then in the Layout component, we add the StaticQuery component to make the query for the menu link data.
The render prop has the result of the query in the data parameter.
And we render the links and title with the Header component.
The div has the child components that we have inside the Layout component tags.
Conclusion
We can restore the scroll position after refresh with Gatsby.
Also, we can get location data from props.
And we can create links dynamically from the site’s metadata.