Data
Query Site MetaData
Add a site title as metadata to the gatsby configuration file.
gatsby-config.js
module.exports = {
+ siteMetadata: {
+ title: `Acme Inc.`,
+ description: `A corporate site`,
+ },
plugins: [`gatsby-plugin-emotion`, "gatsby-plugin-postcss"],
}Open GraphiQL and write a query for the siteMetadata.
http://localhost:8000/___graphQL
query {
site {
siteMetadata {
title
}
}
}
Create a Static Query
Use that query as a static query in the Header component to retrieve the data.
Display the data in the header to the left of the Navigation.
import React from "react"
- import { Link } from "gatsby"
+ import { useStaticQuery, graphql, Link } from "gatsby"
export const NavLink = ({ children, to }) => {
return (
<Link
className="mx-0 p-5 text-gray-600 text-lg hover:text-gray-800 hover:border-2 hover:border-solid hover:border-gray-800"
to={to}
>
{children}
</Link>
)
}
export default function Header() {
+ const data = useStaticQuery(graphql`
+ query {
+ site {
+ siteMetadata {
+ title
+ }
+ }
+ }
+ `)
return (
<header className="pt-5 pb-10 border-b-2 border-solid border-gray-600">
+ <Link to="/" className="text-4xl mx-4">
+ {data.site.siteMetadata.title}
+ </Link>
- <nav>
+ <nav className="inline">
<NavLink to="/">Home</NavLink>
<NavLink to="/about">About</NavLink>
</nav>
</header>
)
}
Query Files
Download these files
Unzip the files.
Copy the
articles
andimages
directories into theacme\src
directory.Install and configure the
gatsby-source-filesystem
plugin so we can read the files in the content directory.npm install gatsby-source-filesystem
gatsby-config.js
module.exports = {
siteMetadata: {
title: `Acme Inc.`,
description: `A corporate site`,
},
plugins: [
+ {
+ resolve: `gatsby-source-filesystem`,
+ options: {
+ name: `src`,
+ path: `${__dirname}/src`,
+ },
+ },
`gatsby-plugin-emotion`,
'gatsby-plugin-postcss',
],
};Save the file and restart the gatsby development server.
Ctrl+C
gatsby developThen open up GraphiQL again.
http://localhost:8000/___graphQL
Write a query to view the file names in the content directory.
{
allFile {
edges {
node {
id
relativePath
prettySize
birthTime(fromNow: true)
}
}
}
}
Create a Page Query
Create a page named
files.js
that uses that uses a the query you just wrote as apage query
to fetch data and then displays it in the page.src\pages\files.js
import { graphql } from "gatsby";
import React from "react";
import Layout from "../components/layout";
import { PageTitle } from "../components/page-title";
const Th = ({ children }) => {
return (
<th className="px-5 py-3 border-b-2 border-gray-200 bg-blue-100 text-left text-xs font-semibold text-gray-600 uppercase tracking-wider">
{children}
</th>
);
};
const Td = ({ children }) => {
return (
<td className="px-5 py-5 border-b border-gray-200 bg-white text-sm">
{children}
</td>
);
};
export default function Files({ data }) {
return (
<Layout>
<PageTitle>Files</PageTitle>
<table className="border border-gray-400 min-w-full leading-normal ">
<thead>
<tr>
<Th>Relative PaTh</Th>
<Th>Pretty Size</Th>
<Th>File Type</Th>
<Th>Created</Th>
</tr>
</thead>
<tbody>
{data.allFile.nodes.map((file) => (
<tr key={file.id}>
<Td>{file.relativePath}</Td>
<Td>{file.prettySize}</Td>
<Td>{file.extension}</Td>
<Td>{file.birthTime}</Td>
</tr>
))}
</tbody>
</table>
</Layout>
);
}
export const query = graphql`
{
allFile {
nodes {
id
relativePath
prettySize
extension
birthTime(fromNow: true)
}
}
}
`;Load the files page and verify the contents.
http://localhost:8000/files/
Tip: visit the development 404 page by typing an invalid url to see a list of all available page routes
Transform Markdown Files into HTML
Install and configure the transformer plugin.
npm install gatsby-transformer-remark
gatsby-config.js
module.exports = {
siteMetadata: {
title: `Acme Inc.`,
description: `A corporate site`,
},
plugins: [
{
resolve: `gatsby-source-filesystem`,
options: {
name: `src`,
path: `${__dirname}/src`,
},
},
+ `gatsby-transformer-remark`,
`gatsby-plugin-emotion`,
"gatsby-plugin-postcss",
],
}Restart the development server then refresh (or open again) GraphiQL.
Query the contents of your articles from the markdown files and transform them to HTML.
query {
allMarkdownRemark {
nodes {
timeToRead
excerpt
frontmatter {
slug
id
title
}
}
}
}Dislay the articles on the home page (
pages\index.js
). *You won't need thehtml
field from the query just theexcerpt
so you can leave it out for now.src\pages\index.html
import { graphql } from "gatsby";
import React from "react";
import Layout from "../components/layout";
import { PageTitle } from "../components/page-title";
export default function Home({ data }) {
console.log(data);
console.log(data.nodes);
return (
<Layout>
<PageTitle>Home</PageTitle>
<img src="https://source.unsplash.com/600x300/?house" alt="house" />
<blockquote className="py-6 text-xl text-gray-800 bg-gray-300 text-center my-6">
"We here at Acme Inc. understand that it is better to leverage
efficiently than to benchmark extensibly."
</blockquote>
<p>
What does the commonly-used commonly-used commonly-accepted industry
jargon "holistic" really mean? What does the term "re-sizing" really
mean? Imagine a combination of WAP and Apache. The ability to
integrate compellingly leads to the power to grow seamlessly. Your
budget for iterating should be at least one-tenth of your budget for
harnessing. If all of this comes off as fabulous to you, that's
because it is! The power to repurpose strategically leads to the
aptitude to productize mega-compellingly. If you redefine
proactively, you may have to maximize dynamically. Do you have a game
plan to become subscriber-defined? Think
micro-intra-clicks-and-mortar, open-source, C2B2B. If all of this
seems confused to you, that's because it is!
</p>
<div className="py-12">
<h2 className="text-xl">Featured Articles</h2>
<hr className="border-gray-400 pb-4" />
{data.allMarkdownRemark.nodes.map((node) => (
<div key={node.frontmatter.id} className="py-2">
<a className="hover:underline " href="">
<h3 className="text-sm text-gray-800 font-semibold tracking-wide uppercase">
{node.frontmatter.title}
</h3>
<p className="">{node.excerpt}</p>
</a>
</div>
))}
</div>
</Layout>
);
}
export const query = graphql`
query {
allMarkdownRemark {
nodes {
timeToRead
excerpt
frontmatter {
slug
id
title
}
}
}
}
`;
Create Pages from Data
Create the directory
src\articles
.Create a file to tell gatsby what routes to dynamically generate:
src\articles\{MarkdownRemark.frontmatter__slug}.js
Create a directory at
src/templates
, and then add the following in a file namedsrc/templates/article.js
.In your browser, visit:
http://localhost:8000/nothing
This is the default 404 page in gatsby that displays all the site pages including the ones you just dynamically created.
Scroll down to the bottom of the Gatsby.js development 404 page and you should see the following article pages were generated.
/articles/recontextualizing-extensibily/
/articles/your-budget-for-streamlining/
/articles/determining-your-feature-set/Note: If you click these page links at this point they will be broken.
Create the basics of a component to display an article but just hard-code a header.
src\pages\articles\{MarkdownRemark.frontmatter__slug}.js
import React from "react";
import Layout from "../../components/layout";
import { PageTitle } from "../../components/page-title";
export default function Article() {
return (
<Layout>
<PageTitle>Article Page</PageTitle>
</Layout>
);
}In your browser, visit:
http://localhost:8000/nothing
Click on of the article links and you should see the
Article Page
header displayed.Article Page
Write a query to find an article based on its slug/path.
Query
sl
Query Variables
Note the id below won't work, you'll have to use a prior query to find an id for your dev environment.
{
"id": "b982e018-50e0-58f0-8ca6-3169483ab7c4"
}
Update the article component as follows:
- Add the query to find an article as page query
- Display the title of the article
- Display the
html
of the article
src\components\article.js
+ import { graphql } from 'gatsby';
import React from 'react';
import Layout from '../components/layout';
import { PageTitle } from "../components/page-title"
+ export default function Article({ data }) {
+ const article = data.markdownRemark;
return (
<Layout>
+ <PageTitle>{article.frontmatter.title}</PageTitle>
+ <div dangerouslySetInnerHTML={{ __html: article.html }} />
</Layout>
);
}
export const query = graphql`
query {
allMarkdownRemark {
nodes {
timeToRead
excerpt
frontmatter {
slug
id
title
}
}
}
}
`
}
Update the article links on the home page to use the slug.
src\pages\index.js
- import { graphql } from "gatsby"
+ import { graphql, Link } from "gatsby"
import React from "react"
import Layout from "../components/layout"
import { PageTitle } from "../components/page-title"
export default function Home({ data }) {
return (
<Layout>
<PageTitle>Home</PageTitle>
...
<div className="py-12">
<h2 className="text-xl">Featured Articles</h2>
<hr className="border-gray-400 pb-4" />
{data.allMarkdownRemark.edges.map(({ node }) => (
<div key={node.frontmatter.id} className="py-2">
- <a className="hover:underline" href="">
+ <Link
+ className="hover:underline"
+ to={`articles${node.frontmatter.slug}`}
+ >
<h3 className="text-sm text-gray-800 font-semibold tracking-wide uppercase">
{node.frontmatter.title}
</h3>
<p className="">{node.excerpt}</p>
- </a>
+ </Link>
</div>
))}
</div>
</Layout>
)
}
export const query = graphql`
query {
allMarkdownRemark {
totalCount
edges {
node {
frontmatter {
id
slug
title
}
timeToRead
excerpt
}
}
}
}
`
Note: The graphql function call returns a Promise see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise for more info