├── .github ├── CODE_OF_CONDUCT.MD ├── CONTRIBUTING.MD ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── custom.md │ └── feature_request.md ├── LICENSE.MD ├── PULL_REQUEST_TEMPLATE.MD └── workflows │ └── nodejs.yml ├── .gitignore ├── .netlify └── state.json ├── README.md ├── gatsby-config.js ├── gatsby-node.js ├── package.json ├── src ├── components │ ├── byline.js │ ├── featured.js │ ├── footer.js │ ├── header.js │ ├── layout.js │ ├── menu.js │ ├── meta.js │ └── seo.js ├── gatsby-plugin-theme-ui │ └── index.js ├── pages │ ├── 404.js │ └── index.js └── templates │ ├── author.js │ ├── category.js │ ├── page.js │ ├── post.js │ └── tag.js └── yarn.lock /.github/CODE_OF_CONDUCT.MD: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | ## Our Standards 8 | 9 | Examples of behavior that contributes to creating a positive environment include: 10 | 11 | * Using welcoming and inclusive language 12 | * Being respectful of differing viewpoints and experiences 13 | * Gracefully accepting constructive criticism 14 | * Focusing on what is best for the community 15 | * Showing empathy towards other community members 16 | 17 | Examples of unacceptable behavior by participants include: 18 | 19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 20 | * Trolling, insulting/derogatory comments, and personal or political attacks 21 | * Public or private harassment 22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission 23 | * Other conduct which could reasonably be considered inappropriate in a professional setting 24 | 25 | ## Our Responsibilities 26 | 27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 28 | 29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 30 | 31 | ## Scope 32 | 33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 34 | 35 | ## Enforcement 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at contact@webdevstudios.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 38 | 39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 40 | 41 | ## Attribution 42 | 43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] 44 | 45 | [homepage]: http://contributor-covenant.org 46 | [version]: http://contributor-covenant.org/version/1/4/ 47 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.MD: -------------------------------------------------------------------------------- 1 | # How To Contribute 2 | 3 | I welcome contributions via feature requests and bug fixes! Here are the steps to get started: 4 | 5 | * Create an [Issue](https://github.com/gregrickaby/gatsby-starter-wordpress-graphql/issues/issues) so we can all discuss your idea 6 | * Fork this repo 7 | * Create a feature or hotfix branch off [master](https://github.com/gregrickaby/gatsby-starter-wordpress-graphql/issues/tree/master) 8 | * Commit code changes to your feature/hotifx branch 9 | * Continue to merge master into your feature/hotifx branch so it stays current 10 | * Please test, test, test your changes across all major browsers 11 | * Submit a [Pull Request](https://github.com/gregrickaby/gatsby-starter-wordpress-graphql/issues/pulls) and reference your Issue # 12 | * If everything tests out on our end, I may merge in your Pull Request 13 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/custom.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Custom issue template 3 | about: Describe this issue template's purpose here. 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | 11 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/LICENSE.MD: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2019 Greg Rickaby 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.MD: -------------------------------------------------------------------------------- 1 | Closes #__ 2 | 3 | ## Description 4 | 5 | 6 | 7 | ## Screenshot 8 | 9 | 10 | 11 | ## Steps for testing 12 | 13 | 14 | -------------------------------------------------------------------------------- /.github/workflows/nodejs.yml: -------------------------------------------------------------------------------- 1 | name: Node CI 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | build: 10 | 11 | runs-on: ubuntu-latest 12 | 13 | strategy: 14 | matrix: 15 | node-version: [10.x] 16 | 17 | steps: 18 | - uses: actions/checkout@v1 19 | - name: Use Node.js ${{ matrix.node-version }} 20 | uses: actions/setup-node@v1 21 | with: 22 | node-version: ${{ matrix.node-version }} 23 | - name: npm install and build 24 | run: | 25 | npm install 26 | npm run build 27 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.gitignore.io/api/node 2 | # Edit at https://www.gitignore.io/?templates=node 3 | 4 | ### Node ### 5 | # Logs 6 | logs 7 | *.log 8 | npm-debug.log* 9 | yarn-debug.log* 10 | yarn-error.log* 11 | lerna-debug.log* 12 | 13 | # Diagnostic reports (https://nodejs.org/api/report.html) 14 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 15 | 16 | # Runtime data 17 | pids 18 | *.pid 19 | *.seed 20 | *.pid.lock 21 | 22 | # Directory for instrumented libs generated by jscoverage/JSCover 23 | lib-cov 24 | 25 | # Coverage directory used by tools like istanbul 26 | coverage 27 | *.lcov 28 | 29 | # nyc test coverage 30 | .nyc_output 31 | 32 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 33 | .grunt 34 | 35 | # Bower dependency directory (https://bower.io/) 36 | bower_components 37 | 38 | # node-waf configuration 39 | .lock-wscript 40 | 41 | # Compiled binary addons (https://nodejs.org/api/addons.html) 42 | build/Release 43 | 44 | # Dependency directories 45 | node_modules/ 46 | jspm_packages/ 47 | 48 | # TypeScript v1 declaration files 49 | typings/ 50 | 51 | # TypeScript cache 52 | *.tsbuildinfo 53 | 54 | # Optional npm cache directory 55 | .npm 56 | 57 | # Optional eslint cache 58 | .eslintcache 59 | 60 | # Optional REPL history 61 | .node_repl_history 62 | 63 | # Output of 'npm pack' 64 | *.tgz 65 | 66 | # Yarn Integrity file 67 | .yarn-integrity 68 | 69 | # dotenv environment variables file 70 | .env 71 | .env.test 72 | 73 | # parcel-bundler cache (https://parceljs.org/) 74 | .cache 75 | 76 | # next.js build output 77 | .next 78 | 79 | # nuxt.js build output 80 | .nuxt 81 | 82 | # vuepress build output 83 | .vuepress/dist 84 | 85 | # Serverless directories 86 | .serverless/ 87 | 88 | # FuseBox cache 89 | .fusebox/ 90 | 91 | # DynamoDB Local files 92 | .dynamodb/ 93 | 94 | # Gatsby 95 | public/ 96 | 97 | # End of https://www.gitignore.io/api/node 98 | -------------------------------------------------------------------------------- /.netlify/state.json: -------------------------------------------------------------------------------- 1 | { 2 | "siteId": "ee5783b5-a642-46e9-bd0d-35866c7c55e3" 3 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # gatsby-starter-wordpress-graphql 2 | 3 | [![Netlify Status](https://api.netlify.com/api/v1/badges/ee5783b5-a642-46e9-bd0d-35866c7c55e3/deploy-status)](https://app.netlify.com/sites/gatsby-starter-wordpress-graphql/deploys) 4 | 5 | A bare-bones [Gatsby](https://gatsbyjs.org) starter powered by [WordPress](https://wordpress.org) and [WPGraphQL](https://www.wpgraphql.com/)! 6 | 7 | Includes support for: 8 | 9 | - Gutenberg via [wp-block-components](https://github.com/danielmilner/wp-block-components) 10 | - Menus 11 | - Posts 12 | - Pages 13 | - Category, Tag, and Author archives 14 | - Basic SEO 15 | - _Sorry, neither WordPress comments nor search don't work just yet. But I welcome your contributions!_ 16 | 17 | 👉🏻[View Demo](https://gatsby-starter-wordpress-graphql.netlify.com) 18 | 19 | WebDevStudios. WordPress for big brands. 20 | 21 | ## WordPress Prerequisites 22 | 23 | The following plugins are required to be activated on a WordPress website: 24 | 25 | 1) [WPGraphQL](https://www.wpgraphql.com/) 26 | 2) [WPGraphQL Gutenberg](https://github.com/pristas-peter/wp-graphql-gutenberg) 27 | 3) [Deploy Netlify Webhook](https://wordpress.org/plugins/webhook-netlify-deploy/) 28 | 29 | These plugins are optional: 30 | 31 | 1) [WPGraphQL ACF](https://github.com/wp-graphql/wp-graphql-acf) 32 | 2) [WPGraphQL Gravity Forms](https://github.com/harness-software/wp-graphql-gravity-forms) 33 | 3) [WPGraphQL Yoast](https://github.com/ashhitch/wp-graphql-yoast-seo) 34 | 35 | 36 | ## Gatsby Development 37 | 38 | ### Download this starter 39 | ```bash 40 | gatsby new https://github.com/gregrickaby/gatsby-starter-wordpress-graphql 41 | ``` 42 | 43 | ### Configure 44 | 45 | Open `gatsby-config.js` and point the URLs at your WordPress websites. 46 | 47 | ### Start a local development server 48 | ```bash 49 | yarn start 50 | ``` 51 | 52 | ### Other handy CLI commands 53 | **Clear Gatsby's cache and start fresh** 54 | ```bash 55 | yarn clean 56 | ``` 57 | 58 | **Build/Test before a deployment** 59 | ```bash 60 | yarn build 61 | ``` 62 | 63 | ## Deployments 64 | 65 | The [demo](https://gatsby-starter-wordpress-graphql.netlify.com) is hosted on [Netlify](https://www.netlify.com/) and deployments are triggered by commits to `master` and with [Deploy Netlify Webhook](https://wordpress.org/plugins/webhook-netlify-deploy/). 66 | 67 | ## Contributing 68 | Feel free to [create an issue](https://github.com/gregrickaby/gatsby-starter-wordpress-graphql/issues) and read about how to [Contribute](https://github.com/WebDevStudios/gatsby-starter-wordpress-graphql/blob/master/.github/CONTRIBUTING.MD). 69 | 70 | ## Props 71 | 72 | Thanks to the awesome Gatsby community for all the ❤️! 73 | -------------------------------------------------------------------------------- /gatsby-config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | siteMetadata: { 3 | siteUrl: "https://gatsby.wdslab.com", 4 | organization: { 5 | name: "WebDevStudios", 6 | url: "https://gatsby.wdslab.com", 7 | logo: 8 | "http://gatsby.wdslab.com/wp-content/uploads/2019/08/wds-logo-small.png" 9 | }, 10 | social: { 11 | twitter: "@webdevstudios", 12 | fbAppID: "" 13 | } 14 | }, 15 | plugins: [ 16 | "gatsby-plugin-react-helmet", 17 | { 18 | resolve: "gatsby-source-filesystem", 19 | options: { 20 | name: "src", 21 | path: `${__dirname}/src/` 22 | } 23 | }, 24 | { 25 | resolve: "gatsby-source-graphql", 26 | options: { 27 | typeName: "WordPress", 28 | fieldName: "wordpress", 29 | url: "https://gatsby.wdslab.com/graphql", 30 | refetchInterval: 60 31 | } 32 | }, 33 | { 34 | resolve: `gatsby-plugin-gtag`, 35 | options: { 36 | // your google analytics tracking id 37 | trackingId: `UA-XXXXXXXX-X`, 38 | // Puts tracking script in the head instead of the body 39 | head: false, 40 | // enable ip anonymization 41 | anonymize: true, 42 | }, 43 | }, 44 | "gatsby-transformer-sharp", 45 | "gatsby-plugin-sharp", 46 | "gatsby-plugin-emotion", 47 | "gatsby-plugin-sitemap", 48 | "gatsby-plugin-theme-ui" 49 | ] 50 | }; 51 | -------------------------------------------------------------------------------- /gatsby-node.js: -------------------------------------------------------------------------------- 1 | // Grab some packages from Node. 2 | const path = require("path"); 3 | const slash = require("slash"); 4 | const { createRemoteFileNode } = require("gatsby-source-filesystem"); 5 | 6 | /** 7 | * Programmatically create posts, pages, and the archives. 8 | * @link https://www.gatsbyjs.org/docs/node-apis/#createPages 9 | */ 10 | exports.createPages = async ({ graphql, actions }) => { 11 | const { createPage } = actions; 12 | 13 | // Run a GraphQL query. 14 | const result = await graphql(` 15 | query { 16 | wordpress { 17 | posts { 18 | edges { 19 | node { 20 | id 21 | postId 22 | slug 23 | status 24 | } 25 | } 26 | } 27 | pages { 28 | edges { 29 | node { 30 | id 31 | pageId 32 | slug 33 | status 34 | } 35 | } 36 | } 37 | categories { 38 | edges { 39 | node { 40 | id 41 | categoryId 42 | slug 43 | description 44 | name 45 | } 46 | } 47 | } 48 | tags { 49 | edges { 50 | node { 51 | id 52 | tagId 53 | slug 54 | description 55 | name 56 | } 57 | } 58 | } 59 | users { 60 | edges { 61 | node { 62 | id 63 | userId 64 | name 65 | slug 66 | } 67 | } 68 | } 69 | } 70 | } 71 | `); 72 | 73 | // Error checking. 74 | if (result.errors) { 75 | throw new Error(result.errors); 76 | } 77 | 78 | // Destructure data. 79 | const { posts, pages, categories, tags, users } = result.data.wordpress; 80 | 81 | // Create posts. 82 | const postTemplate = path.resolve(`./src/templates/post.js`); 83 | posts.edges.forEach(edge => { 84 | createPage({ 85 | path: `/${edge.node.slug}/`, 86 | component: slash(postTemplate), 87 | context: { 88 | id: edge.node.id, 89 | wordpress_id: edge.node.pageId 90 | } 91 | }); 92 | }); 93 | 94 | // Create pages. 95 | const pageTemplate = path.resolve(`./src/templates/page.js`); 96 | pages.edges.forEach(edge => { 97 | createPage({ 98 | path: `/${edge.node.slug}/`, 99 | component: slash(pageTemplate), 100 | context: { 101 | id: edge.node.id 102 | } 103 | }); 104 | }); 105 | 106 | // Create category archives. 107 | const categoryTemplate = path.resolve(`./src/templates/category.js`); 108 | categories.edges.forEach(edge => { 109 | createPage({ 110 | path: `/category/${edge.node.slug}/`, 111 | component: slash(categoryTemplate), 112 | context: { 113 | id: edge.node.id 114 | } 115 | }); 116 | }); 117 | 118 | // Create tag archives. 119 | const tagTemplate = path.resolve(`./src/templates/tag.js`); 120 | tags.edges.forEach(edge => { 121 | createPage({ 122 | path: `/tag/${edge.node.slug}/`, 123 | component: slash(tagTemplate), 124 | context: { 125 | id: edge.node.id 126 | } 127 | }); 128 | }); 129 | 130 | // Create author archives. 131 | const authorTemplate = path.resolve(`./src/templates/author.js`); 132 | users.edges.forEach(edge => { 133 | createPage({ 134 | path: `/author/${edge.node.slug}/`, 135 | component: slash(authorTemplate), 136 | context: { 137 | id: edge.node.id 138 | } 139 | }); 140 | }); 141 | }; 142 | 143 | /** 144 | * Download WordPress images, add them to GraphQL schema. 145 | * @link https://www.gatsbyjs.org/docs/node-apis/#createResolvers 146 | * @link https://www.gatsbyjs.org/packages/gatsby-source-filesystem/?=#createremotefilenode 147 | */ 148 | exports.createResolvers = async ({ 149 | actions, 150 | cache, 151 | createNodeId, 152 | createResolvers, 153 | store 154 | }) => { 155 | const { createNode } = actions; 156 | const resolvers = { 157 | WordPress_MediaItem: { 158 | imageFile: { 159 | type: "File", 160 | resolve: source => { 161 | return createRemoteFileNode({ 162 | cache, 163 | createNode, 164 | createNodeId, 165 | store, 166 | url: source.sourceUrl 167 | }); 168 | } 169 | } 170 | } 171 | }; 172 | await createResolvers(resolvers); 173 | }; 174 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gatsby-starter-wordpress-graphql", 3 | "version": "0.0.1", 4 | "description": "A Gatsby stater powered by WordPress and GraphQL!", 5 | "repository": { 6 | "url": "https://github.com/webdevstudios/gatsby-starter-wordpress-graphql" 7 | }, 8 | "license": "MIT", 9 | "keywords": [ 10 | "gatsby", 11 | "graphql", 12 | "wordpress" 13 | ], 14 | "dependencies": { 15 | "@emotion/core": "^10.0.27", 16 | "@emotion/styled": "^10.0.27", 17 | "@mdx-js/react": "^1.5.5", 18 | "gatsby": "^2.19.1", 19 | "gatsby-image": "^2.2.39", 20 | "gatsby-plugin-emotion": "^4.1.21", 21 | "gatsby-plugin-gtag": "^1.0.12", 22 | "gatsby-plugin-react-helmet": "^3.1.21", 23 | "gatsby-plugin-sharp": "^2.4.0", 24 | "gatsby-plugin-sitemap": "^2.2.26", 25 | "gatsby-plugin-theme-ui": "^0.2.53", 26 | "gatsby-source-filesystem": "^2.1.46", 27 | "gatsby-source-graphql": "^2.1.31", 28 | "gatsby-transformer-sharp": "^2.3.13", 29 | "prop-types": "^15.7.2", 30 | "react": "^16.12.0", 31 | "react-dom": "^16.12.0", 32 | "react-helmet": "^5.2.1", 33 | "theme-ui": "^0.2.52", 34 | "wp-block-components": "^0.2.0" 35 | }, 36 | "scripts": { 37 | "start": "gatsby develop", 38 | "build": "gatsby build", 39 | "clean": "gatsby clean" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/components/byline.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Link, graphql } from "gatsby"; 3 | 4 | const Byline = ({ props }) => ( 5 | <> 6 | 12 | 13 | {" "} 14 | by{" "} 15 | 16 | {props.author.name} 17 | 18 | {" "} 19 | {null === props.commentCount ? `` : `with ${props.commentCount} comments`} 20 | 21 | ); 22 | 23 | export default Byline; 24 | 25 | export const query = graphql` 26 | fragment AuthorQuery on WordPress_Post { 27 | author { 28 | name 29 | slug 30 | } 31 | } 32 | `; 33 | -------------------------------------------------------------------------------- /src/components/featured.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { graphql } from "gatsby"; 3 | import Img from "gatsby-image"; 4 | 5 | const FeaturedImage = ({ props }) => { 6 | // No featured image? Bail... 7 | if (!props.featuredImage) { 8 | return null; 9 | } 10 | 11 | // Otherwise display featured image. 12 | return ( 13 | {props.altText} 17 | ); 18 | }; 19 | 20 | export default FeaturedImage; 21 | 22 | export const query = graphql` 23 | fragment FeaturedImageQuery on WordPress_Post { 24 | featuredImage { 25 | altText 26 | sourceUrl 27 | imageFile { 28 | childImageSharp { 29 | fluid(maxWidth: 960) { 30 | ...GatsbyImageSharpFluid_tracedSVG 31 | } 32 | } 33 | } 34 | } 35 | } 36 | `; 37 | -------------------------------------------------------------------------------- /src/components/footer.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import PropTypes from "prop-types"; 3 | /** @jsx jsx */ 4 | import { jsx, Container } from "theme-ui"; 5 | 6 | const Footer = ({ siteTitle }) => ( 7 | 21 | ); 22 | 23 | Footer.propTypes = { 24 | siteTitle: PropTypes.string 25 | }; 26 | 27 | Footer.defaultProps = { 28 | siteTitle: `` 29 | }; 30 | 31 | export default Footer; 32 | -------------------------------------------------------------------------------- /src/components/header.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import PropTypes from "prop-types"; 3 | import { Link } from "gatsby"; 4 | import Menu from "./menu"; 5 | /** @jsx jsx */ 6 | import { jsx, Container, Flex, useColorMode } from "theme-ui"; 7 | 8 | const Header = ({ siteTitle, siteDescription }) => { 9 | const modes = ["default", "swiss", "deep", "dark"]; 10 | const [mode, setMode] = useColorMode(); 11 | const cycleMode = e => { 12 | const i = modes.indexOf(mode); 13 | const next = modes[(i + 1) % modes.length]; 14 | setMode(next); 15 | }; 16 | return ( 17 |
18 | 25 | 26 |

27 | 28 |

29 |

33 | 34 | 35 |

36 | 47 | 48 | 49 |
50 | ); 51 | }; 52 | 53 | Header.propTypes = { 54 | siteTitle: PropTypes.string, 55 | siteDescription: PropTypes.string 56 | }; 57 | 58 | Header.defautProps = { 59 | siteTitle: ``, 60 | siteDescription: `` 61 | }; 62 | 63 | export default Header; 64 | -------------------------------------------------------------------------------- /src/components/layout.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import PropTypes from "prop-types"; 3 | import { StaticQuery, graphql } from "gatsby"; 4 | import Header from "./header"; 5 | import Footer from "./footer"; 6 | import { Global } from "@emotion/core"; 7 | import { Layout as ThemeLayout, Container, Main } from "theme-ui"; 8 | 9 | const Layout = ({ children }) => ( 10 | ( 22 | <> 23 | 30 | 31 |
35 | 36 |
{children}
37 |
38 |