CSS-modules Emotion
e.g. Typography
npm install --save gatsby-plugin-typography react-typography typography typography-theme-fairy-gates
// gatsby-config.js
module.exports = {
plugins: [
{
resolve: `gatsby-plugin-typography`,
options: {
pathToConfigModule: `src/utils/typography`,
},
},
],
}
And a config file:
// src/utils/typography.js
import Typography from "typography"
import fairyGateTheme from "typography-theme-fairy-gates"
const typography = new Typography(fairyGateTheme)
export const { scale, rhythm, options } = typography
export default typography
- Page queries on page components
- StaticQuery hooks on non-page components
GraphiQL IDE
http://localhost:8000/___graphql
CTRL + Space = autocomplete popup
CTRL + Enter = run query
Source plugins:
e.g.
npm install --save gatsby-source-filesystem
//gatsby-config.js
plugins: [
{
resolve: `gatsby-source-filesystem`,
options: {
name: `src`,
path: `${__dirname}/src/`,
},
}
]
e.g. npm install --save gatsby-transformer-remark
to gatsby-config.js gatsby-transformer-remark
for transforming markdown
- Query data with GraphQL
- Map the query results to pages using template
using 2 Gatsby APIs - onCreateNode() and createPages()
// gatsby-node.js
const path = require(`path`)
const { createFilePath } = require(`gatsby-source-filesystem`)
exports.onCreateNode = ({ node, getNode, actions }) => {
const { createNodeField } = actions
if (node.internal.type === `MarkdownRemark`) {
const slug = createFilePath({ node, getNode, basePath: `pages` })
createNodeField({
node,
name: `slug`,
value: slug,
})
}
}
exports.createPages = ({ graphql, actions }) => {
// **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
const { createPage } = actions
return graphql(`
{
allMarkdownRemark {
edges {
node {
fields {
slug
}
}
}
}
}
`
).then(result => {
console.log(JSON.stringify(result, null, 4))
result.data.allMarkdownRemark.edges.forEach(({ node }) => {
createPage({
path: node.fields.slug,
component: path.resolve(`./src/templates/blog-post.js`),
context: {
// Data passed to context is available
// in page queries as GraphQL variables.
slug: node.fields.slug,
},
})
})
})
}
// src/templates/blog-post.js
import React from "react"
import { graphql } from "gatsby"
import Layout from "../components/layout"
export default ({ data }) => {
const post = data.markdownRemark
return (
<Layout>
<div>
<h1>{post.frontmatter.title}</h1>
<div dangerouslySetInnerHTML={{ __html: post.html }} />
</div>
</Layout>
)
}
export const query = graphql`
query($slug: String!) {
markdownRemark(fields: { slug: { eq: $slug } }) {
html
frontmatter {
title
}
}
}
`
List of links to generated pages from index.js
// src/pages/index.js
import React from "react"
import { Link, graphql } from "gatsby"
import Layout from "../components/layout"
export default ({ data }) => {
return (
<Layout>
<div>
<h4>{data.allMarkdownRemark.totalCount} Posts</h4>
{data.allMarkdownRemark.edges.map(({ node }) => (
<div key={node.id}>
<Link
to={node.fields.slug}
>
<h3>
{node.frontmatter.title}{" "}
— {node.frontmatter.date}
</span>
</h3>
<p>{node.excerpt}</p>
</Link>
</div>
))}
</div>
</Layout>
)
}
export const query = graphql`
query {
allMarkdownRemark(sort: { fields: [frontmatter___date], order: DESC }) {
totalCount
edges {
node {
id
frontmatter {
title
date(formatString: "DD MMMM, YYYY")
}
fields {
slug
}
excerpt
}
}
}
}
`
- create production build w
gatsby build
gatsby serve
=> localhost:9000- Lighthouse Audit
- manifest.webmanifest w
npm install --save gatsby-plugin-manifest
- add favicon 'src/images/icon.png'
- serviceworker w
npm install --save gatsby-plugin-offline
- add page metadata w
npm install --save gatsby-plugin-react-helmet react-helmet
(see https://github.com/nfl/react-helmet)
// gatsby-config.js
{
plugins: [
{
resolve: `gatsby-plugin-manifest`,
options: {
name: `GatsbyJS`,
short_name: `GatsbyJS`,
start_url: `/`,
background_color: `#6b37bf`,
theme_color: `#6b37bf`,
// Enables "Add to Homescreen" prompt and disables browser UI (including back button)
// see https://developers.google.com/web/fundamentals/web-app-manifest/#display
display: `standalone`,
icon: `src/images/icon.png`, // This path is relative to the root of the site.
},
},
`gatsby-plugin-offline`,
`gatsby-plugin-react-helmet`,
]
}
import React from "react"
import { Helmet } from "react-helmet"
class Application extends React.Component {
render() {
return (
<div className="application">
<Helmet>
<meta charSet="utf-8" />
<title>My Title</title>
<link rel="canonical" href="http://mysite.com/example" />
</Helmet>
...
</div>
)
}
}