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.