Your computer should be ready for Gatsby v4 and have installed:
- Node (v16.x)
- Yarn (v1.22.x)
- NPM (8.x)
- Git
- Gatsby-CLI
Use git to clone the code repository
git clone git@github.com:octahedroid/badcamp-2022-gatsby.git
cd badcamp-2022-gatsby
Install dependencies
yarn install
Start Gatsby on develop mode
yarn develop
❯ tree src/
Â
yarn start
Open the browser and point to http://localhost:8000/
Open the browser and point to http://localhost:8000/___graphql
{
allSitePage {
nodes {
id
path
}
}
}
yarn add gatsby-source-drupal-graphql
NOTE: This was done already no need to execute this command
Add plugin configuration to gatsby-config.js
file
{
resolve: `gatsby-source-drupal-graphql`,
options: {
baseUrl: process.env.DRUPAL_BASE_URL,
endPoint: process.env.DRUPAL_ENDPOINT,
environment: process.env.NODE_ENV,
concurrency: 10,
auth: {
oauth: {
baseUrl: process.env.DRUPAL_BASE_URL,
user: process.env.DRUPAL_AUTH_USERNAME,
password: process.env.DRUPAL_AUTH_PASSWORD,
clientId: process.env.DRUPAL_AUTH_CLIENT_ID
},
},
},
},
cp .env.dist .env.development
cp .env.dist .env.production
NOTE: Copy values from instructor shared screen
yarn start
Open the browser and point to http://localhost:8000/___graphql
Copy/paste the following GraphQl query
{
allDrupalNodePage {
nodes {
id
title
path
body {
processed
}
}
}
}
Copy/paste the following GraphQl query
{
allDrupalNodeArticle {
nodes {
id
title
path
body {
processed
}
image {
mediaImage {
url
}
gatsbyImage {
childImageSharp {
gatsbyImageData
}
}
}
}
}
}
Copy/paste the following GraphQl query
Create gatsby-node.js
file and paste code
const path = require("path");
exports.createPages = async ({ graphql, actions }) => {
return graphql(`
query {
allDrupalNodeArticle {
nodes {
id
path
}
}
allDrupalNodePage {
nodes {
id
path
}
}
}
`).then((result) => {
if (result.errors) {
throw result.errors;
}
// Create allDrupalNodeArticle
const articles = result.data.allDrupalNodeArticle.nodes;
articles.forEach((article) => {
actions.createPage({
path: article.path,
component: path.resolve("src/templates/article.js"),
context: {
id: article.id,
},
});
});
// Create allDrupalNodePage
const pages = result.data.allDrupalNodePage.nodes;
pages.forEach((page) => {
actions.createPage({
path: page.path === "/home" ? "/" : page.path,
component: path.resolve("src/templates/page.js"),
context: {
id: page.id,
},
});
});
});
};
Create src/templates/article.js
file and paste code
import React from "react";
import { graphql } from "gatsby";
import Container from "../components/container";
import Header from "../components/header";
import Footer from "../components/footer";
export default function Article({ data: { node } }) {
return (
<Container>
<Header />
<article className="prose prose-lg max-w-6xl mx-auto">
<pre>
{ JSON.stringify(node, {}, 2) }
</pre>
</article>
<Footer />
</Container>
);
}
export const query = graphql`
query drupalNodeArticle($id: String) {
node: drupalNodeArticle(id: {eq: $id}) {
title
body {
processed
}
}
}
`
Create src/templates/page.js
file and paste code
import React from "react";
import { graphql } from "gatsby";
import Container from "../components/container";
import Header from "../components/header";
import Footer from "../components/footer";
export default function Page({ data: { node } }) {
return (
<Container>
<Header />
<article className="prose prose-lg max-w-6xl mx-auto">
<pre>
{ JSON.stringify(node, {}, 2) }
</pre>
</article>
<Footer />
</Container>
);
}
export const query = graphql`
query drupalNodePage($id: String) {
node: drupalNodePage(id: {eq: $id}) {
title
body {
processed
}
}
}
`
Remove src/pages/index.js
index file
Open page file src/templates/page.js
Remove JSON output
<pre>
{ JSON.stringify(node, {}, 2) }
</pre>
Import components
import Title from "../components/field/title";
import Body from "../components/field/body";
Add components to the page
<Title>{node.title}</Title>
<Body
content={node?.body?.processed}
/>
Open page file src/templates/page.js
Add showTitle
to GraphLQ Query
showTitle
Replace original code:
<Title>{node.title}</Title>
With this code containing the showTitle value validation to show/hide the title component
{ node.showTitle && <Title>{node.title}</Title> }
Open gatsby-config.js
file and add configuration
inlineImages: {
'NodeArticle': ['body'],
'NodePage': ['body'],
}
Open page file src/templates/page.js
Add processedWithInlineImages
field to GraphLQ Query
# GraphQL Customization Fields
fields {
processedWithInlineImages
}
Update Body
component to use previously added field
<Body
content={node.fields.processedWithInlineImages}
/>
Instead of
<Body
content={node?.body?.processed}
/>
Check
gatsby-node.js
for code to replace image relativePath with remotePath
Open page file src/templates/page.js
Add inlineImages
field to GraphLQ Query
# GraphQL Customization Fields
fields {
...
inlineImages {
remotePath
gatsbyImage {
childImageSharp {
gatsbyImageData(width: 1024)
}
}
}
}
Replace original Body
compoenent with BodyInlineImages
:
import BodyInlineImages from "../components/field/body-inline-images";
With the recently imported BodyInlineImages
component
<BodyInlineImages
content={node?.fields?.processedWithInlineImages}
inlineImages={node.fields.inlineImages}
/>
Add components
field
components {
__typename
...ParagraphBlogTeaser
...ParagraphHeroCta
...ParagraphImage
...ParagraphText
}
Check
src/helpers/fragments.js
for code related to GraphQL query fragments
Import uuid
library and componentResolver
helper
import uuid from "react-uuid"
import { componentResolver } from "../helpers/component-resolver"
Call componentResolver
helper
const components = componentResolver(node?.components);
NOTE: Check
src/helpers/component-resolver.js
file for resolvers
<BodyInlineImages
content={node?.fields?.processedWithInlineImages}
inlineImages={node.fields.inlineImages}
/>
With the components
array constant
{components &&
components.map((item) => {
return <React.Fragment key={uuid()}>{item}</React.Fragment>
})}
<article className="prose prose-lg max-w-6xl mx-auto">
It should look like this:
<article>
Open page file src/templates/article.js
Remove JSON output
<pre>
{ JSON.stringify(node, {}, 2) }
</pre>
Add fields to GraphQL Query
created
author {
displayName
picture {
gatsbyImage {
childImageSharp {
gatsbyImageData(layout: FIXED, width: 48, height: 48)
}
}
}
}
image {
gatsbyImage {
childImageSharp {
gatsbyImageData(width: 1500)
}
}
}
Add code
const author = {
name: node.author.displayName,
picture: node.author.picture.gatsbyImage.childImageSharp,
}
Import component
import Cover from "../components/cover";
Add Cover
component to the page
<Cover
className="prose prose-lg max-w-6xl mx-auto"
title={node.title}
coverImage={node.image.gatsbyImage.childImageSharp}
date={node.created}
author={author}
/>
Add components
field
components {
__typename
...ParagraphHeroCta
...ParagraphHeroText
...ParagraphImage
...ParagraphText
...ParagraphCodeBlock
}
import uuid from "react-uuid"
import { componentResolver } from "../helpers/component-resolver"
Call componentResolver
helper
const components = componentResolver(node?.components);
And render the components
array constant
{components &&
components.map((item) => {
return <React.Fragment key={uuid()}>{item}</React.Fragment>
})}
<article className="prose prose-lg max-w-6xl mx-auto">
It should look like this:
<article>
Used Drupal Modules:
- https://www.drupal.org/project/graphql_compose
- https://www.drupal.org/project/simple_oauth
- https://www.drupal.org/project/build_hooks
Other Drupal Modules: